The current implementation of UndefinedClassesOrProperties finds triples where a class or property is expected in the object position and then looks whether that “object resource” is accessible for the VocabularyReader. If a resource was found, it does not check whether the resource actually is a class or property. (Example below.)
So we need to check whether the data we found for that resource (usually: the data we downloaded from the object URI) contains something that convinces us that it is an rdfs:Class or an owl:Class, or an rdf:Property. (Note that if something is an owl:Class it is also an rdfs:Class, and that OWL defines a lot of special cases of rdf:Property, such as owl:ObjectProperty or owl:TransitiveProperty. I can write down the full list here once we are starting to implement this; please let me know.)
Let <o> be the URI of the object. From just looking at the data, without doing OWL reasoning, we can look for, e.g. <o> rdf:type owl:Class and will know that the triple <...> rdf:type <o> is a “good” triple w.r.t. this metric. We can even look for <o> ?p ?o and will know that …
if ?p is rdfs:subClassOf or owl:unionOf or owl:intersectionOf or owl:equivalentClass or owl:oneOf, then <o> is an rdfs:Class.
if ?p is rdfs:domain or rdfs:subPropertyOf or rdfs:range or owl:propertyDisjointWith or owl:equivalentProperty, then <o> is an rdf:Property.
if ?p is owl:disjointUnionOf or owl:complementOf or owl:disjointWith or owl:hasKey, then <o> is an rdfs:Class.
if ?p is owl:inverseOf or owl:propertyChainAxiom, then <o> is an rdf:Property.
Example: imagine a triple <...> rdf:type socialnetwork:Alice where socialnetwork:Alice rdf:type foaf:Person, i.e. socialnetwork:Alice is actually not an owl:Class but an owl:Individual (which is declared to be disjoint with owl:Class). This is a “bad triple” even if socialnetwork:Alice is defined.
The current implementation of UndefinedClassesOrProperties finds triples where a class or property is expected in the object position and then looks whether that “object resource” is accessible for the VocabularyReader. If a resource was found, it does not check whether the resource actually is a class or property. (Example below.)
So we need to check whether the data we found for that resource (usually: the data we downloaded from the object URI) contains something that convinces us that it is an
rdfs:Class
or anowl:Class
, or anrdf:Property
. (Note that if something is anowl:Class
it is also anrdfs:Class
, and that OWL defines a lot of special cases ofrdf:Property
, such asowl:ObjectProperty
orowl:TransitiveProperty
. I can write down the full list here once we are starting to implement this; please let me know.)Let
<o>
be the URI of the object. From just looking at the data, without doing OWL reasoning, we can look for, e.g.<o> rdf:type owl:Class
and will know that the triple<...> rdf:type <o>
is a “good” triple w.r.t. this metric. We can even look for<o> ?p ?o
and will know that …?p
isrdfs:subClassOf
orowl:unionOf
orowl:intersectionOf
orowl:equivalentClass
orowl:oneOf
, then<o>
is anrdfs:Class
.?p
isrdfs:domain
orrdfs:subPropertyOf
orrdfs:range
orowl:propertyDisjointWith
orowl:equivalentProperty
, then<o>
is anrdf:Property
.?p
isowl:disjointUnionOf
orowl:complementOf
orowl:disjointWith
orowl:hasKey
, then<o>
is anrdfs:Class
.?p
isowl:inverseOf
orowl:propertyChainAxiom
, then<o>
is anrdf:Property
.Example: imagine a triple
<...> rdf:type socialnetwork:Alice
wheresocialnetwork:Alice rdf:type foaf:Person
, i.e.socialnetwork:Alice
is actually not anowl:Class
but anowl:Individual
(which is declared to be disjoint withowl:Class
). This is a “bad triple” even ifsocialnetwork:Alice
is defined.