How to list root classes of an ontology in SPARQL? - sparql

I am trying to list root classes of the NIF ontology which is an ontology created of several other ontologies as its modules.
I use this code from an online resource:
SELECT ?directSub ?super
WHERE { ?directSub rdfs:subClassOf ?super .
FILTER NOT EXISTS {
?directSub rdfs:subClassOf ?otherSub .
FILTER (?otherSub != ?directSub)
}
}
The logic of the code seems fine but it does not return any answers (even when I test it on other ontologies)! Why is that?

The #UninformedUser's answer works fine. However, there is an exception that does not work with that solution, which is a root class without any child. The solution assumes that all roots have subclasses, which is not always true.
The following piece of code can find these classes:
SELECT DISTINCT ?exClass
WHERE {
?exClass rdf:type owl:Class
FILTER NOT EXISTS { ?subClass rdfs:subClassOf ?exClass }
FILTER NOT EXISTS { ?exClass rdfs:subClassOf ?supClass }}
Hence, the full SPARQL query for finding all root nodes is:
SELECT DISTINCT ?rootClass
WHERE {{
?rootClass rdf:type owl:Class .
?subClass rdf:type owl:Class .
?subClass rdfs:subClassOf ?rootClass
FILTER NOT EXISTS {
?rootClass rdfs:subClassOf ?otherSup
FILTER (?otherSup != owl:Thing)}
} UNION {
?rootClass rdf:type owl:Class
FILTER NOT EXISTS { ?subClass rdfs:subClassOf ?rootClass }
FILTER NOT EXISTS { ?rootClass rdfs:subClassOf ?supClass }}}
I am sure that the above pieces of code can be improved, however, I am just a beginner. I really would appreciate it if someone can provide tips on how to improve it.

Related

How to get the top level classes from an ontology with SPARQL and filter out classes restrictions in the query?

I know there's some answers from Query SPARQL resulting level 1 hierarchy and SPARQL Query - get top-level classes of a dataset
But this isn't enough for what I'm trying to do. I have the class Category, subclass of owl:Thing, and the query
SELECT DISTINCT ?cls
WHERE {
?cls a owl:Class .
FILTER NOT EXISTS {
?cls rdfs:subClassOf ?sup .
FILTER(?sup != owl:Thing)
}
}
works fine for other classes without restrictions but it doesn't return Category because Category has restrictions, which this query sees them as separate classes. My Category class looks like this:
:Category rdf:type owl:Class ;
rdfs:subClassOf owl:Thing ,
[ rdf:type owl:Restriction ;
owl:onProperty :hasConfidence ;
owl:minCardinality "0"^^xsd:nonNegativeInteger
] ,
[ rdf:type owl:Restriction ;
owl:onProperty :hasIntensity ;
owl:minCardinality "0"^^xsd:nonNegativeInteger
] ,
[ rdf:type owl:Restriction ;
owl:onProperty :hasConfidence ;
owl:maxCardinality "1"^^xsd:nonNegativeInteger
] ,
[ rdf:type owl:Restriction ;
owl:onProperty :hasIntensity ;
owl:maxCardinality "1"^^xsd:nonNegativeInteger
] ;
rdfs:comment """Category refers to the classification used to annotate the emotion.
This can be further expanded to add support to new categories."""#en ;
rdfs:label "Category"#en .
How can I modify the query to add these top-level classes that are "subclasses" of some restrictions? I need a FILTER for those restrictions but I don't know how to go into this. I tried doing
SELECT DISTINCT ?cls
WHERE
{
{
?cls a owl:Class .
FILTER NOT EXISTS {
?cls rdfs:subClassOf ?sup .
FILTER(?sup != owl:Thing)
}
}
UNION
{ ?cls rdfs:subClassOf owl:Thing }
}
and it works but that implies that Category has to be EXPLICITLY subclass of owl:Thing, which isn't always the case in a lot of ontologies.
I figured it out. Here's the query for anyone who's having trouble with this like me:
SELECT DISTINCT ?cls
WHERE
{
?cls a owl:Class .
FILTER NOT EXISTS {
?cls rdfs:subClassOf ?sup .
FILTER(?sup != owl:Thing) .
FILTER NOT EXISTS {
?sup a owl:Restriction .
}
}
FILTER(?cls != owl:Thing) # We get rid of the root class from the query results
}
Basically, all I needed was a filter for the owl:Restriction class types. I also added a filter to get rid of owl:Thing from the query results. With this query I'm able to get the Category class from my ontology, which is part of the top-layer / level 1 hierarchy.

Join has cross-product in SPARQL query

I am trying to come up with a trivial minimal functional example of a federated query not using any web interface or something, but a local query engine (in my case AG free tier).
Now this at least doesn't throw any errors and returns stuff, but I'm getting a warning that the query contains a cross-product. Now I guess the problem is that there is nothing that actually relates the results from the two endpoints.
join has cross-product. Unique LHS variables: ?actor_1_1, ?birthDate, ?spouseURI_1_2, ?spouseName; Unique RHS variables ?actor_2_1, ?gender
But how do I relate them then? In a generic manner, since I guess this information needs to be passed to the query-resolver, and eventually I'll query other databases.
PREFIX dbpo: <http://dbpedia.org/ontology/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
SELECT ?birthDate ?spouseName ?gender {
{ SERVICE <https://dbpedia.org/sparql>
{ SELECT ?birthDate ?spouseName WHERE {
?actor rdfs:label "Arnold Schwarzenegger"#en ;
dbpo:birthDate ?birthDate ;
dbpo:spouse ?spouseURI .
?spouseURI rdfs:label ?spouseName .
FILTER ( lang(?spouseName) = "en" )
}
}
}
{ SERVICE <https://query.wikidata.org/sparql>
{ SELECT ?gender WHERE {
?actor wdt:P1559 "Arnold Alois Schwarzenegger"#de .
?actor wdt:P21 ?gender .
}
}
}
}
I'd appreciate any help here, I haven't had as hard a time getting into a subject since forever.

SPARQL Query not returning depth

I have the following SPARQL Query:
SELECT ?depthClass (count(?mid)-1 as ?depth)
WHERE {
{
SELECT ?root WHERE {
?root a owl:Class
FILTER NOT EXISTS {
?root rdfs:subClassOf ?superroot
filter ( ?root != ?superroot )
}
}
}
?depthClass rdfs:subClassOf* ?mid .
?mid rdfs:subClassOf* ?root .
}
group by ?depthClass
order by ?depth
It is supposed to return the class and the depth of the given class depthClass. However, it does not return anything. I don't see any error in the query.
After debugging I noticed that, since I was using owlready2 rdflib implementation, it probably did not support ?root a owl:Class syntax, after changing it to ?root rdf:type owl:Class it started working!

Translate nouns using SPARQL with Babelnet

The following query translates a word to a certain language:
SELECT DISTINCT ?translation WHERE {
?entries a lemon:LexicalEntry .
?entries rdfs:label "apple"#en .
?entries lemon:sense ?sense .
?sense lexinfo:translation ?translation .
filter contains(str(?translation),"HI")
}
But how can I retrieve the label for the translation, which is a LexicalSense as far I can tell
The way up and the way down is one and the same (as Heraclitus had said):
SELECT DISTINCT ?label WHERE {
?original_entry rdfs:label "apple"#en .
?original_entry lemon:sense ?original_sense .
?original_sense
lexinfo:translation
?translated_sense .
?translated_entry lemon:sense ?translated_sense .
?translated_entry rdfs:label ?label .
FILTER (lang(?label) = "hi")
}
Try it!
This page describes data model and provides some example queries.

SPARQL query on Protege for Number of Classes

In order to determine the number of classes in a .owl file,
I was advised to use the following SPARQL query:
SELECT ( count(?class) as ?count )
WHERE { graph <put_your_model_graph_name_here> { ?class a owl:Class . } }
However, when I replace the put_your_model_graph_name_here with my ontology IRI, I get 0
I also tried http://blahblahblah followed immediately by # to no avail.
What am I doing wrong?
Difficult to tell without seeing how you are loading and querying the data. Try using:
SELECT ( count(?class) as ?count ) { ?class a owl:Class }
which will query the default graph, or
SELECT ?g ( count(?class) as ?count )
{ graph ?g { ?class a owl:Class } }
group by ?g
which will give counts for all the named graphs.