Reputation: 1006
I have a class ABC
that is a subClassOf
the class XYZ
and defined as intersections of classes A
, B
, C
as:
<Class rdf:about="&clink;ABC">
<equivalentClass>
<Class>
<intersectionOf rdf:parseType="Collection">
<Restriction>
<onProperty rdf:resource="&clink;affects"/>
<someValuesFrom rdf:resource="&clink;A"/>
</Restriction>
<Restriction>
<onProperty rdf:resource="&clink;hasMarker"/>
<someValuesFrom rdf:resource="&clink;B"/>
</Restriction>
<Restriction>
<onProperty rdf:resource="&clink;hasPathologicalProcess"/>
<someValuesFrom rdf:resource="&clink;C"/>
</Restriction>
</intersectionOf>
</Class>
</equivalentClass>
<rdfs:subClassOf rdf:resource="&clink;XYZ"/>
</Class>
How I can get access to the classes A
, B
and C
through the class XYZ
using SPARQL query in RDFLib?
The following query returns a blank node rdflib.term.BNode('_L')
and I don't know how to handle the BNodes.
PREFIX rdf: h<ttp://www.w3.org/2000/01/rdf-schema#>
SELECT ?subclass
WHERE {<XYZ> <rdf:subClassOf> <subclass>}
I need a query that receive the XYZ
and returns this:
A
B
C
Upvotes: 2
Views: 676
Reputation: 1531
First of all, XYZ
is neither a subClassOf
A
, B
, C
nor a subClassOf
their intersection A and B and C
(I am using manchester syntaax (see here)).
In your snippet, you define XYZ
to be equivalentTo
(which implies being a subClassOf
as well) of the intersection of three anynomous (see here) classes; which are (affects some A) and (hasMaker some B) and (hasPathologicalProcess some C)
. This intersection is not equivalent to A and B and C
(some
in Manchester syntax stands for someValuesFrom
).
To understand what someValuesFrom
restriction means, see the documentation (see here) of OWL:
The value constraint
owl:someValuesFrom
is a built-in OWL property that links a restriction class to a class description or a data range. A restriction containing anowl:someValuesFrom
constraint describes a class of all individuals for which at least one value of the property concerned is an instance of the class description or a data value in the data range. In other words, it defines a class of individuals x for which there is at least oney
(either an instance of the class description or value of the data range) such that the pair(x,y)
is an instance ofP
. This does not exclude that there are other instances(x,y')
ofP
for whichy'
does not belong to the class description or data range.
EDIT2:
Now that you should have understood what owl:someValuesFrom
means, and as @AKSW suggests, here is a straightforward SPARQL query. However, you cannot retrieve A
, B
, and C
simply using rdfs:subClassOf
! You should first retrieve the restriction, then access the property and the class it is defined on, as follows:
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
select ?eqclass ?restriction ?onProp ?someValuesFrom where {
{?eqclass owl:equivalentClass/owl:intersectionOf _:b. _:b rdf:first ?restriction}
# First anonymous class (restriction) in the collection
UNION { ?eqclass owl:equivalentClass/owl:intersectionOf/(rdf:rest+/rdf:first+)* ?restriction.}
# getting other anonymous classes (restriction) using property paths and rdf:first and rdf:rest used in RDF collections.
?restriction rdf:type owl:Restriction.
# individuals of type owl:Restriction
?restriction owl:onProperty ?onProp.
# the property the restriciton is defined on which
?restriction owl:someValuesFrom ?someValuesFrom.
# the class of the owl:someValuesFrom property
}
End of EDIT2
Other work around through modifying your data model.
So first, your query should return the anonymous class (affects some A) and (hasMaker some B) and (hasPathologicalProcess some C)
which is the intersection you define. However, as it is an anonymous class, a blank node B_node
will be returned for it, rather than a concrete class. To return a concrete class, you should define this anonymous intersection as a class in your ontology for this intersection; for example, you can create the class anyn_intersection
, as follows:
<owl:Class rdf:about="myPrefix#anyn_intersection">
<owl:equivalentClass>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<owl:Restriction>
<owl:onProperty rdf:resource="myPrefix#affects"/>
<owl:someValuesFrom rdf:resource="myPrefix#A"/>
</owl:Restriction>
<owl:Restriction>
<owl:onProperty rdf:resource="myPrefix#hasMaker"/>
<owl:someValuesFrom rdf:resource="myPrefix#B"/>
</owl:Restriction>
<owl:Restriction>
<owl:onProperty rdf:resource="myPrefix#hasPathologicalProcess"/>
<owl:someValuesFrom rdf:resource="myPrefix#C"/>
</owl:Restriction>
</owl:intersectionOf>
</owl:Class>
</owl:equivalentClass>
</owl:Class>
Thus, your query will get this class anyn_intersection
instead of the blank node.
Now If you want to get all of (affects some A)
, (hasMaker some B)
, and (hasPathologicalProcess some C)
in the results, you should first make sure that a reasoner is running because this is an implicit knowledge and second you should for each anonymous intersection class, define a concrete intersection class in a similar way to the anyn_intersection
above. For example, you can define anyn_AffectsSomeA
for the anonymous restriction class: affects some A
as follows:
<owl:Class rdf:about="myPrefix#anyn_AffectsSomeA">
<owl:equivalentClass>
<owl:Restriction>
<owl:onProperty rdf:resource="myPrefix#affects"/>
<owl:someValuesFrom rdf:resource="myPrefix#A"/>
</owl:Restriction>
</owl:equivalentClass>
</owl:Class>
Then you have to define two similar classes anyn_hasMakerSomeB
and anyn_hasPathologicalProcessSomeC
. Finally, you define anyn_intersection
as the intersection of anyn_AffectsSomeA
, anyn_hasMakerSomeB
, and anyn_hasPathologicalProcessSomeC
.
EDIT1:
I am not aware if there is some specific feature in rdfLib
that enables you to retrieve anonymous classes definitions. That might solve your problem without having to define it the way I suggest. Additionally, you should make sure a reasoner is running.
End of EDIT1:
Upvotes: 3