Skip to content

Commit

Permalink
Define top-level class core:UcoThing; test for top-levelness
Browse files Browse the repository at this point in the history
This patch is known to fail CI due to the new test.  It is posted early
for definition-comment feedback.

References:
* #430

Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
  • Loading branch information
ajnelson-nist committed Aug 23, 2022
1 parent d7eeaad commit 51f3723
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
14 changes: 13 additions & 1 deletion ontology/uco/core/core.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,9 @@ core:UcoObject
owl:Class ,
sh:NodeShape
;
rdfs:subClassOf core:UcoThing ;
rdfs:label "UcoObject"@en ;
rdfs:comment "A UCO object is a representation of a fundamental concept either directly inherent to the cyber domain or indirectly related to the cyber domain and necessary for contextually characterizing cyber domain concepts and relationships. Within the Unified Cyber Ontology (UCO) structure this is the base class acting as a consistent, unifying and interoperable foundation for all explicit and inter-relatable content objects."@en ;
rdfs:comment "A UCO object is a representation of a fundamental concept either directly inherent to the cyber domain or indirectly related to the cyber domain and necessary for contextually characterizing cyber domain concepts and relationships. Within the Unified Cyber Ontology (UCO) structure this is a base class acting as a consistent, unifying and interoperable foundation for all explicit and inter-relatable content objects."@en ;
owl:disjointWith core:Facet ;
sh:property
[
Expand Down Expand Up @@ -396,6 +397,17 @@ core:UcoObject
sh:targetClass core:UcoObject ;
.

core:UcoThing
a
owl:Class ,
sh:NodeShape
;
rdfs:subClassOf owl:Thing ;
rdfs:label "UcoThing"@en ;
rdfs:comment "UcoThing is the top-level class within UCO."@en ;
sh:targetClass core:UcoThing ;
.

core:confidence
a owl:DatatypeProperty ;
rdfs:label "confidence"@en ;
Expand Down
33 changes: 32 additions & 1 deletion tests/test_uco_monolithic.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@

import pytest
import rdflib.plugins.sparql.processor
from rdflib import BNode, Graph, Literal, RDF, URIRef
from rdflib import BNode, Graph, Literal, Namespace, RDF, URIRef
from rdflib.term import Node

IdentifiedNode = Union[BNode, URIRef]

NS_UCO_CORE = Namespace("https://ontology.unifiedcyberontology.org/uco/core/")


@pytest.fixture(scope="module")
def graph() -> Generator[Graph, None, None]:
Expand Down Expand Up @@ -162,3 +164,32 @@ def test_semi_open_vocabulary_owl_shacl_alignment(graph: Graph) -> None:
computed.add((test_case[0], test_case[1], shacl_tuple, rdfs_tuple))

assert expected == computed


def test_only_one_uco_class_is_owl_thing_direct_subclass(graph: Graph) -> None:
"""
UCO expects all classes defined in UCO namespaces (i.e. excluding the "import review" ontologies) are subclasses of core:UcoThing. Within OWL, absence of an rdfs:subClassOf statement implies being a subclass of owl:Thing. Review UCO for any accidental omission of rdfs:subClassOf.
"""
expected: Set[URIRef] = {NS_UCO_CORE.UcoThing}
computed: Set[URIRef] = set()
for result in graph.query("""\
SELECT ?nClass
WHERE {
{
?nClass rdfs:subClassOf owl:Thing .
}
UNION
{
?nClass a owl:Class .
FILTER NOT EXISTS {
?nClass rdfs:subClassOf ?nOtherClass .
}
}
FILTER isIRI(?nClass)
}
"""):
n_class: URIRef = result[0]
if not str(n_class).startswith("https://ontology.unifiedcyberontology.org/uco/"):
continue
computed.add(n_class)
assert expected == computed

0 comments on commit 51f3723

Please sign in to comment.