I'm trying to create SPARQL query that returns individuals which are an instance of an equivalent class expression (thus imitating some of the reasoning skills of protégé on Semantic Web). Can anyone help me figure out how to do this? I have a class named 'violation' which contains an equivalent class restriction. Now I want to find the individuals that meet the conditions of this restriction.
This is my query so far:
SELECT distinct ?Carmovement ?person ?restriction ?message
WHERE {?Carmovement carmovement:has_driver ?person .
?Carmovement rdf:type ?restriction . #rdf:type is no succes for getting instances
?object owl:equivalentClass ?restriction .
?object violin:message ?message}`
The query does not give any results because I have used "rdf:type", I wonder in which way I can evaluate whether an instance meets the condition of a class restriction.
Sample class restriction:
owl:equivalentClass [ rdf:type owl:Class ;
owl:intersectionOf (
<http://desibo.frsf.utn.edu.ar/ontologies/2012/9/CarMovement.owl#Car_Movement>
[ rdf:type owl:Restriction ;
owl:onProperty <http://desibo.frsf.utn.edu.ar/ontologies/2012/9/CarMovement.owl#has_driver> ;
owl:allValuesFrom <http://desibo.frsf.utn.edu.ar/ontologies/2012/9/CarMovement.owl#BarredPerson>
]
)
] ;
I expect to get individuals who have a property "has_driver" of type "BarredPerson".
Related
I want to create a subgraph consisting of only "Disorder sub-hierarchy" of SNOMED. I am trying to create this subgraph from the complete SNOMED-OWL graph using a SPARQL CONSTRUCT query. However the property consisting of owl:equivalentCLass/ owl:intersectionOf / owl:Restriction shows an empty [] in the created subgraph. The same query displays correct result in the ontology editor window. I am new to SPARQL and OWL. Can someone please help me with traversing the complex owl axioms in attribute relationships so that the subgraph is created correctly.
I have used the SPARQL query tab provided in the free edition of TopBraid ontology editor Version 6.0.1 (tbcfe-6.0.1). This is the query the I tried. I had provided screenshots in my question earlier but they are not clearly visible I guess.
#select disorder concepts containing "and" and lenght <=4 words
CONSTRUCT {?s ?p ?o}
WHERE
{
?s rdfs:label ?fsn
bind(replace(?fsn, "\\S", "") as ?space)
bind(strlen(?space) as ?spacecount)
FILTER(REGEX(?fsn," and ") && REGEX(?fsn,"(disorder)"))
FILTER(?spacecount<=3).
?s ?p ?o
}
ORDER BY ?spacecount
This query displays the correct output in TopBraid editor retrieved results but when I export them to a .ttl file, I get a blank [] wherever there are complex owl axioms like owl:intersectionOf, owl:EquivalentClass, owl:restriction, etc.
**Concept in original file**
<http://snomed.info/id/188487008> rdf:type owl:Class ;
rdfs:subClassOf [ owl:intersectionOf ( <http://snomed.info/id/64572001>
[ rdf:type owl:Restriction ;
owl:onProperty <http://snomed.info/id/609096000> ;
owl:someValuesFrom [ rdf:type owl:Restriction ;
owl:onProperty <http://snomed.info/id/116676008> ;
owl:someValuesFrom <http://snomed.info/id/128929007>
]
]
) ;
rdf:type owl:Class
] ;
rdfs:label "Lymphosarcoma and reticulosarcoma (disorder)"#en ;
skos:prefLabel "Lymphosarcoma and reticulosarcoma"#en .
**Concept created/exported in Subgraph**
:188487008 a owl:Class ;
rdfs:label "Lymphosarcoma and reticulosarcoma (disorder)"#en ;
rdfs:subClassOf owl:Thing ;
rdfs:subClassOf [] ;
skos:prefLabel "Lymphosarcoma and reticulosarcoma"#en .
I have referred this solution but it doesn't seem to work for me and gives an empty resultset- (SPARQL: how to transfer owl:equivalentClass to rdfs:subClassOf (owl:Restriction) properties?)
Screenshots
Ontology editor displays the ?o correctly
Generated subgraph file has a blank [] for ?o
I'm trying to get my head around inferring RDF data. Say that I have these triples (RDF Turtle), which I created using Protege:
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
:hasSpouse rdf:type owl:ObjectProperty ,
owl:SymmetricProperty ;
rdfs:domain :People ;
rdfs:range :People .
:People rdf:type owl:Class .
:Jane_Doe rdf:type owl:NamedIndividual ,
:People .
:John_Doe rdf:type owl:NamedIndividual ,
:People ;
:hasSpouse :Jane_Doe .
The reasoner in Protege will kindly highlight the expected inference, that is :Jane_Doe :hasSpouse :John_Doe.
How can I see that inference with SPARQL? If I run this query in Protege (SPARQL tab):
SELECT ?subject
WHERE {?subject hasSpouse ?object .}
It shows the asserted triple, not the inferred one. I understand how to do it manually, e.g. :
CONSTRUCT {?object ?prop ?subject }
WHERE { ?prop rdf:type owl:SymmetricProperty .
?subject ?prop ?object .}
I'd see now the inferred data I'm expecting but 1) that would be losing the point imho (i.e; reinventing the wheel) 2) I cannot have 2 queries in this tab (construct, then select). There's got to be a way to do this automatically, just like the reasoner did.
I read in Stack Overflow a post saying to use 'Snap SPARQL' plugin in Protege. I tried but simple queries don't work (like the first one above). It's like it's a different language. How does it work?
So, how can I get the benefit of these owl properties with SPARQL? How can I have an OWL-aware SPARQL in Protege? Am I taking this the wrong way? What's the right way?
thanks for your help.
Nicolas
You need to make your inferences a part of your knowledge.
To do so, go to the SWRL Tab and click successively on the button
at the bottom of that Tab, start from the left to the right.
Let's say we have the owl:Class Person and the owl:Class Fruit. Besides that we have the owl:ObjectProperty loves (Domain: Person, Range: Fruit). There are several instances of both classes.
Is it possible to express in OWL that one particular instance of the class Person likes all fruits except apples (instance of Fruit) without having to manually define all of the loves-relations between that person and all the other Fruit instances (except apple)?
On a more abstract level: Is it possible to define relations between an instance and a range of instances (either on a class-level or for the instance itself)?
OneOf restrictions are used for what you're describing. To exclude one instance from a class (for the first part of your question) you can intersect the fruit class and the negation of OneOf(Apple), and use it to declare your apple hater as having as type a range assertion for your love property.
The solution to your problem depends whether "apple" is an instance of "fruit" or "apple" is a subclass of "fruit". It would make more sense to say that "apple" is a class, because there are many instances of apples. But since Ignazio presented a solution where "apple" is an instance, and that his answer was accepted, I will start with assuming that "apple" is an instance. Then you can achieve what you want with:
:Fruit a owl:Class .
:apple a :Fruit .
:Person a owl:Class .
:bob a :Person .
:loves a owl:ObjectProperty .
[ a owl:Class;
owl:intersectionOf (
:Fruit
[ a owl:Class; owl:complementOf [a owl:Class; owl:oneOf (:apple)] ]
)
] rdfs:subClassOf [
a owl:Restriction;
owl:onProperty [ owl:inverseOf :loves ];
owl:hasValue :bob
] .
This is saying that everything that is a :Fruit and is not :apple is necessary loved by :bob (assuming :bob is the identifier of the person who does not like apples. Note that this is different from Ignazio's solution, which does not exactly model what the OP wants.
Now, if there is a class of apples, then the solution would be:
:Fruit a owl:Class .
:Apple rdfs:subClassOf :Fruit .
:Person a owl:Class .
:bob a :Person .
:loves a owl:ObjectProperty .
[ a owl:Class;
owl:intersectionOf (
:Fruit
[ a owl:Class; owl:complementOf :Apple ]
)
] rdfs:subClassOf [
a owl:Restriction;
owl:onProperty [ owl:inverseOf :loves ];
owl:hasValue :bob
] .
We are trying to get a reasoner (e.g. HermiT in Protege) to infer that a more specific sub-property can be used instead of the asserted general property.
Classes:
- Patient
- Finding
- Dyspnea
- ObservationStatus
- Inclusion
- Exclusion
Properties:
- has_finding (domain: Patient, range: Finding)
- has_positive_finding (domain: Patient, range: Finding, Inclusion)
- has_negative_finding (domain: Patient, range: Finding, Exclusion)
If we assert the following triples:
:Patient1 a :Patient .
:Patient1 :has_negative_finding :Dyspnea1 .
A reasoner can infer (among other things) that:
:Dyspnea1 a :Finding .
:Dyspnea1 a :Exclusion.
But when we look at it the other way around and assert:
:Patient1 a :Patient .
:Dyspnea1 a :Dyspnea .
:Dyspnea1 a :Exclusion .
:Patient1 :has_finding :Dyspnea1.
We would like the reasoner to infer that:
:Patient1 :has_negative_finding :Dyspnea1 .
We cannot seem to get Protege and HermiT to draw that conclusion and infer the triples.
What are we missing? Are the conditions not necessary and sufficient for it to infer that knowledge?
:Patient1 a :Patient .
:Dyspnea1 a :Dyspnea .
:Dyspnea1 a :Exclusion .
:Patient1 :has_finding :Dyspnea1.
We would like the reasoner to infer that:
:Patient1 :has_negative_finding :Dyspnea1 .
… What are we missing? Are the conditions not necessary and sufficient
for it to infer that knowledge?
There are a few issues here.
First, you haven't said that every has_finding actually corresponds to one of the subproperties. That is, just because something has as finding, you don't know that it also has a negative or a positive finding. The finding could just be a general finding, without being one of the more specific ones.
Second, the more specific type of the object doesn't mean that you have to use the more specific property.
Third, even if you state that the finding is an exclusion, if you don't know that exclusions are disjoint from inclusions, you could still have the finding be both a positive and negative finding.
Now, what it'd be really nice to do would be to state that has_finding is the union of has_negative_finding and has_positive_finding, and then declare inclusion and exclusion disjoint. Then every instance of a finding would have to be one or the other, and you could make your inference.
Since you can't do that, you'll need some sort of alternative. If you're using individuals as per-person diagnoses, then you could say that every finding is either a negative finding or a positive finding with an axiom like
(inverse(hasFinding) some Patient) subClass ((inverse(hasNegativeFinding) some Patient) or (inverse(hasPositiveFinding) some Patient))
along with making hasFinding inverse functional, so that each finding is associated with at most one patient. Then you'd have an ontology like this:
#prefix : <http://stackoverflow.com/a/30903552/1281433/> .
#prefix a: <http://stackoverflow.com/a/30903552/1281433/> .
#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#> .
a:Exclusion a owl:Class ;
rdfs:subClassOf a:Finding .
a:hasNegativeFinding a owl:ObjectProperty ;
rdfs:range a:Exclusion ;
rdfs:subPropertyOf a:hasFinding .
_:b0 a owl:Restriction ;
owl:onProperty a:hasPositiveFinding ;
owl:someValuesFrom a:Inclusion .
a: a owl:Ontology .
[ a owl:Restriction ;
rdfs:subClassOf [ a owl:Class ;
owl:unionOf ( _:b1 _:b0 )
] ;
owl:onProperty a:hasFinding ;
owl:someValuesFrom a:Finding
] .
a:Finding a owl:Class ;
owl:disjointUnionOf ( a:Finding a:Inclusion ) .
a:patient1 a owl:Thing , owl:NamedIndividual ;
a:hasFinding a:dyspnea1 .
_:b1 a owl:Restriction ;
owl:onProperty a:hasNegativeFinding ;
owl:someValuesFrom a:Exclusion .
a:hasFinding a owl:ObjectProperty .
a:Inclusion a owl:Class ;
rdfs:subClassOf a:Finding .
a:hasPositiveFinding a owl:ObjectProperty ;
rdfs:range a:Inclusion ;
rdfs:subPropertyOf a:hasFinding .
a:dyspnea1 a owl:NamedIndividual , a:Exclusion .
and you can get results like this:
I have create an endpoint SPAQL on OpenLink Virtuoso.
All work well, but i have to access on the data in a Container, in particular a rdf:Seq.
I have a Seq like this:
<myrdf:has_stoptimes>
<rdf:Seq rdf:about="http://test.com/343">
<rdf:li>
<myrdf:StopTime rdf:about="http://test.com/StopTime/434">
...
</ns0:StopTime>
</rdf:li>
<rdf:li>
<myrdf:StopTime rdf:about="http://test.com/StopTime/435">
...
</ns0:StopTime>
</rdf:li>
</rdf:Seq>
Now i see that to access data in a container i can use rdfs:member or FILTER (strstarts(str(?prop), str(rdf:_)) how is explained here
But for my project i have to adopt the first solution because i'm working with Silk and i will use the code syntax like ?a/myrdf:has_stoptimes/rdfs:member without use of "complex" filter.
I have tried to follow this guide but querying the endpoint nothing work how i hoped.
So my question is: how can i query ?a/myrdf:has_stoptimes/rdfs:member on a Virtuoso endpoint SPARQL?Which inference rule i have to add in endpoint SPARQL?
Thank you in advance
UPDATE
I have created the following inference rules in Virtuoso:
ttlp (' #prefix rdfs: .
#prefix rdf: .
rdfs:Container rdf:type rdfs:Class ; rdfs:subClassOf rdfs:Resource .
rdfs:ContainerMembershipProperty a rdfs:Class ; rdfs:subClassOf rdf:Property .
rdf:Seq rdf:type rdfs:Class ; rdfs:subClassOf rdfs:Container .
rdfs:member rdf:type rdf:Property ; rdfs:domain rdfs:Resource ; rdfs:range rdfs:Resource .
', '', 'http://localhost:8890/schema/test') ;
Nothing work querying the SPARQL endpoint like:
define input:inference "http://localhost:8890/schema/property_rules1"
SELECT *
FROM
WHERE {?sep a rdf:Seq.
?seq rdfs:member ?p}
After i tried adding the follow line to the ttl file: rdf:_1 rdfs:subPropertyOf rdfs:member . In this way it work but obviously the results are only for the first element of the container. So is very unconvenient add a line for all of rdf:_n, and i think this is only a temporary solution, it is not correct.
I have tried to add an RDF dump on SILK 2.6.1, and on the section SPARQL of the data source if i run the query:
SELECT *
FROM
WHERE {?sep a rdf:Seq.
?seq rdfs:member ?p}
I obtain the correct result, without specify any inference rules. So i think that in this functionality of SILK there is something that i’m missing in my endpoint SPARQL or am i saying nonsense things?
You can't use variables in property paths, so you can't actually do
?x ?a/has_stoptimes/rdfs:member ?y
Instead, you have to use another variable or blank node in between:
?x ?a ?z . ?z has_stoptimes/rdfs:member ?y
?x ?a [ has_stoptimes/rdfs:member ?y ] .