SPARQL Query not returning depth - sparql

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!

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.

Why does a bound variable not work inside a FILTER in a UNION BLOCK?

The following query works as expected:
PREFIX nct: <http://n2t.net/ark:/39333/ncg/type#>
PREFIX ncv: <http://n2t.net/ark:/39333/ncg/vocab#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT ?label ?url WHERE {
BIND("Chapel Hill" as ?placename)
{
?marker
a nct:HistoricalMarker ;
skos:prefLabel ?label ;
skos:note ?markerDescription ;
.
FILTER CONTAINS(?markerDescription, "Chapel Hill")
}
UNION
{
?musician skos:prefLabel ?label .
?place
skos:prefLabel ?placename ;
ncv:associatedWithAgent ?musician ;
.
}
UNION
{
?movie skos:prefLabel ?label .
?place
skos:prefLabel ?placename ;
ncv:filmingLocationFor ?movie ;
.
}
}
But if I change FILTER CONTAINS(?markerDescription, "Chapel Hill") in the first block to FILTER CONTAINS(?markerDescription, ?placename), it no longer works.
Try the working query.
Try the not working query.
Why?

How to list root classes of an ontology in 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.

Getting super and sub classes of Dbpedia Ontology

I am trying to get the hierarchy of super and subclass of dbpedia ontolgy.
Sparql query:
SELECT DISTINCT ?superclass ?subclass
WHERE
{
?subclass a owl:Class .
?subclass rdfs:subClassOf ?superclass
}
ORDER BY ?superclass ?subclass
It gives me all classes. But when I am trying to get the counts of entity inside classes. Some classes have entity while some don't have.
Sparql query to get the count of entity inside classes.
Getting Entities:
SELECT DISTINCT ?label AS ?label
?name AS ?name
?link AS ?link
WHERE
{
?link rdf:type <http://www.wikidata.org/entity/Q12136> .
OPTIONAL { ?link foaf:name ?name }
OPTIONAL { ?link rdfs:label ?label }
FILTER( lang(?label) = "en" )
}
Not getting Entities:
SELECT DISTINCT ?label AS ?label
?name AS ?name
?link AS ?link
WHERE
{
?link rdf:type <http://www.wikidata.org/entity/Q18553493> .
OPTIONAL { ?link foaf:name ?name }
OPTIONAL { ?link rdfs:label ?label }
FILTER(lang(?label) = "en" )
}
Why some classes don't have entities? Or Am I doing something wrong? Any help please?
First of all, you are talking about classes and not ontologies. I don't know why you think that entities are instances of ontologies, especially when you're talking about individuals/instances/resources.
Second, why shouldn't there be classes that do not have instances yet?

SPARQL BIND function Syntax error

Hi Guys am trying run a SPARQL query on Virtuoso version 6.1.x. Here is the query:
SPARQL PREFIX fns: <NAMESPACE> SELECT ?birth ?death ?age ?value ?typeId FROM <http://freebaseInc5>
WHERE { fns:m.030pk7c fns:people.person.date_of_birth ?birth; fns:people.deceased_person.date_of_death ?death; BIND(year(?death)-year(?birth) as ?age ) .
OPTIONAL {?mid fns:common.topic.notable_types ?type . ?type fns:type.object.id ?typeId } .
OPTIONAL {?mid fns:type.object.name ?value FILTER langMatches(lang(?value), "en") }}
I am getting the error complaining about the syntax:
> SQLState: 37000
Message: SQ074: Line 4: SP030: SPARQL compiler, line 2: syntax error at 'BIND' before '('
SPARQL PREFIX fns: <NAMESPACE> SELECT ?birth ?death ?age ?value ?typeId FROM <NAMESPACE>
WHERE { fns:m.030pk7c fns:people.person.date_of_birth ?birth; fns:people.deceased_person.date_of_death ?death; BIND(year(?death)-year(?birth) as ?age ) .
OPTIONAL {?mid fns:common.topic.notable_types ?type . ?type fns:type.object.id ?typeId } .
OPTIONAL {?mid fns:type.object.name ?value FILTER langMatches(lang(?value), "en") }}
I don't see what the error is; what am I missing?
It's actually legal SPARQL…
Here's your query, with improved formatting, and with the "SPARQL" removed from the beginning, but no other changes:
PREFIX fns: <NAMESPACE>
SELECT ?birth ?death ?age ?value ?typeId
FROM <http://freebaseInc5>
WHERE {
fns:m.030pk7c fns:people.person.date_of_birth ?birth ;
fns:people.deceased_person.date_of_death ?death ;
BIND(year(?death)-year(?birth) as ?age ) .
OPTIONAL {
?mid fns:common.topic.notable_types ?type .
?type fns:type.object.id ?typeId
} .
OPTIONAL {
?mid fns:type.object.name ?value
FILTER langMatches(lang(?value), "en")
}
}
According to sparql.org's query validator, the query is well formed (which actually suprised me, given the ; after ?death, but I guess it's OK after all).
…but Virtuoso doesn't like it.
But if I try to run this on DBpedia's endpoint, which runs Virtuoso, (along with a limit 1, just to make sure it's not actually going to use much in the way of resources), I see the error you're talking about:
Virtuoso 37000 Error SP030: SPARQL compiler, line 10: syntax error at 'BIND' before '('
SPARQL query:
define sql:big-data-const 0
#output-format:text/html
define sql:signal-void-variables 1 define input:default-graph-uri <http://dbpedia.org> PREFIX fns: <NAMESPACE>
SELECT ?birth ?death ?age ?value ?typeId
FROM <http://freebaseInc5>
WHERE {
fns:m.030pk7c fns:people.person.date_of_birth ?birth ;
fns:people.deceased_person.date_of_death ?death ;
BIND(year(?death)-year(?birth) as ?age ) .
OPTIONAL {
?mid fns:common.topic.notable_types ?type .
?type fns:type.object.id ?typeId
} .
OPTIONAL {
?mid fns:type.object.name ?value
FILTER langMatches(lang(?value), "en")
}
}
LIMIT 1
However, if you change the ; after ?death to ., or remove it completely, the query is accepted without any problem.