lambdamusic / Ontospy

Python library and command-line interface for inspecting and visualizing RDF models aka ontologies.
http://lambdamusic.github.io/Ontospy/
MIT License
219 stars 52 forks source link

custom datatype is mis-identified as a class instead of a property #27

Closed CyberDaedalus00 closed 5 years ago

CyberDaedalus00 commented 7 years ago

If an ontology contains a custom datatype by extending a standard one, such as xsd:string, Ontospy identifies it as a class. For example:

 <rdfs:Datatype rdf:about="http://www.example.com/cti_common#structuredText">
    <rdfs:comment xml:lang="en-US">Specifies that the text description is formatted utilizing an encoding scheme.</rdfs:comment>
    <rdfs:label xml:lang="en-US">Structured Text</rdfs:label>
    <rdfs:subClassOf rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
  </rdfs:Datatype>

The example code above defines a custom datatype http://www.example.com/cti_common#structuredText by extending through subclassing http://wwww.w3.org/2001/XMLSchema#string. When this ontology is loaded into OntoSpy, it is identified as a class as shown below:

>>> model.printClassTree()
cti:ChangeStatement
cti:Note
cti:Reference
cti:structuredText

Yet when you retrieve the class using model.getClass("structuredText") and theserialize you get the following:

>>> model.getClass("structuredText")
[<Class *http://www.example.com/cti_common#structuredText*>]
>>> a_class = _[0]
>>> print(a_class.serialize())
@prefix cti: <http://www.example.com/cti_common#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix vs: <http://www.w3.org/2003/06/sw-vocab-status/ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

cti:structuredText a rdfs:Datatype ;
    rdfs:label "Structured Text"@en-US ;
    rdfs:comment "Specifies that the text description is formatted utilizing an encoding scheme."@en-US ;
    rdfs:subClassOf xsd:string .

This appears to be because in QueryHelper.py, the method getAllClasses treats anything RDF entity that has an refs:subClassOf as a class.

lambdamusic commented 5 years ago

Looking at this again, I think there is an issue with your implementation.

A custom datatype is normally implemented as an instance of rdfs:Datatype. I'm not an expert about this but I dug around a bit and found some useful background info:

In your example you are declaring an instance to be a subclass of another instance. This makes it implicitly a set (= a class). That is, according to the rdfs schema specs:

A triple of the form:
C1 rdfs:subClassOf C2
states that C1 is an instance of rdfs:Class, C2 is an instance of rdfs:Class and C1 is a subclass of C2. The rdfs:subClassOf property is transitive.

So I think Ontospy is not deriving any false inference. That instance is indeed also a class.

Makes sense?