简体   繁体   中英

Calculate the depth of subclass in the OWL ontology

I'm looking for a SPARQL query that could return the position of specified subclass in the OWL hierarchy. I have studied several examples but the best result I could ever reach is the computation the relative paths between the specified superclass and its subclasses ( thanks to Joshua Taylor ). Instead of that I need to calculate the "absolute" depth for a given subclass.

My ontology contains several top-level classes and every of them is followed with a separate tree of subclasses. Here is part of my OWL (converted to TTL with a rdfcat utility):

@prefix :      <http://www.semanticweb.org/administrator/ontologies/2014/7/untitled-ontology-9#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd:   <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .

:depression  a              owl:Class ;
    rdfs:subClassOf  :pit .

:pit    a                owl:Class ;
    rdfs:subClassOf  :on_the_road .

:on_the_road  a            owl:Class ;
    rdfs:subClassOf  :traffic_accident .

:traffic_accident  a  owl:Class .

In this case for a given depression class I expect to get 3 , pit -> 2 , on_the_road -> 1 , traffc_accident (a top-level class) -> 0.

The same approach works here for finding the depth of a class in a hierarchy (assuming, of course, that each class has a unique path to a root). The trick is just that you first need to find the roots of the hierarchy. You can do that with the following query to get the following results.

prefix : <http://www.semanticweb.org/administrator/ontologies/2014/7/untitled-ontology-9#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ?class (count(?mid)-1 as ?depth) {
  #-- Select root classes (classes that have no
  #-- superclasses other than themselves).
  {
    select ?root {
      ?root a owl:Class
      filter not exists {
        ?root rdfs:subClassOf ?superroot 
        filter ( ?root != ?superroot )
      }
    }
  }

  ?class rdfs:subClassOf* ?mid .
  ?mid rdfs:subClassOf* ?root .
}
group by ?class
order by ?depth
-----------------------------
| class             | depth |
=============================
| :traffic_accident | 0     |
| :on_the_road      | 1     |
| :pit              | 2     |
| :depression       | 3     |
-----------------------------

Note that things may be a bit more complicated if you've got a reasoner. If you've got a reasoner, then every class, including your roots, is a subclass of owl:Thing, so there will actually only be one root, and all the depths will be off by one (from what you've mentioned in the question). You can avoid that by adjusting the filters in the query that finds values for ?root.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM