Skip to content

Commit 2a908c7

Browse files
committed
Add past CDO ontology and version IRIs to existing-concept review
A follow-on patch will regenerate Make-managed files. References: * #40 Signed-off-by: Alex Nelson <alexander.nelson@nist.gov>
1 parent 4941189 commit 2a908c7

File tree

7 files changed

+176
-3
lines changed

7 files changed

+176
-3
lines changed

CONTRIBUTE.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ pushd case_utils/ontology
2727
git add case-0.6.0.ttl # Assuming CASE 0.6.0 was just released.
2828
# and/or
2929
git add uco-0.8.0.ttl # Assuming UCO 0.8.0 was adopted in CASE 0.6.0.
30+
31+
git add ontology_and_version_iris.txt
3032
popd
3133
make check
3234
# Assuming `make check` passes:
33-
git commit -m "Build CASE 0.6.0 monolithic .ttl files" case_utils/ontology/case-0.6.0-subclasses.ttl case_utils/ontology/case-0.6.0.ttl
35+
git commit -m "Build CASE 0.6.0 monolithic .ttl files" case_utils/ontology/case-0.6.0-subclasses.ttl case_utils/ontology/case-0.6.0.ttl case_utils/ontology/ontology_and_version_iris.txt
3436
git commit -m "Update CASE ontology pointer to version 0.6.0" dependencies/CASE case_utils/ontology/version_info.py
3537
```
3638

@@ -43,4 +45,4 @@ pre-commit --version
4345
The `pre-commit` tool hooks into Git's commit machinery to run a set of linters and static analyzers over each change. To install `pre-commit` into Git's hooks, run:
4446
```bash
4547
pre-commit install
46-
```
48+
```

case_utils/case_validate/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ def main() -> None:
180180
_logger.debug("arg_ontology_graph = %r.", arg_ontology_graph)
181181
ontology_graph.parse(arg_ontology_graph)
182182

183+
# Construct set of CDO concepts for data graph concept-existence review.
183184
cdo_concepts: typing.Set[rdflib.URIRef] = set()
185+
184186
for n_structural_class in [
185187
NS_OWL.Class,
186188
NS_OWL.AnnotationProperty,
@@ -214,6 +216,16 @@ def main() -> None:
214216
continue
215217
cdo_concepts.add(ontology_triple[0])
216218

219+
# Also load historical ontology and version IRIs.
220+
ontology_and_version_iris_data = importlib.resources.read_text(
221+
case_utils.ontology, "ontology_and_version_iris.txt"
222+
)
223+
for line in ontology_and_version_iris_data.split("\n"):
224+
cleaned_line = line.strip()
225+
if cleaned_line == "":
226+
continue
227+
cdo_concepts.add(rdflib.URIRef(cleaned_line))
228+
217229
data_cdo_concepts: typing.Set[rdflib.URIRef] = set()
218230
for data_triple in data_graph.triples((None, None, None)):
219231
for data_triple_member in data_triple:

case_utils/ontology/Makefile

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ RDF_TOOLKIT_JAR := $(uco_srcdir)/lib/rdf-toolkit.jar
2424
case_version := $(shell python3 version_info.py)
2525

2626
all: \
27-
case-$(case_version)-subclasses.ttl
27+
ontology_and_version_iris.txt
2828

2929
.PRECIOUS: \
3030
case-$(case_version).ttl
@@ -79,3 +79,16 @@ case-$(case_version)-subclasses.ttl: \
7979
clean:
8080
@rm -f \
8181
case-$(case_version)*.ttl
82+
83+
ontology_and_version_iris.txt: \
84+
src/ontology_and_version_iris.py \
85+
case-$(case_version)-subclasses.ttl
86+
# Guarantee venv is built. (Same rationale as in the subclasses.ttl recipe.)
87+
$(MAKE) \
88+
--directory $(case_srcdir)/tests \
89+
.venv.done.log
90+
source $(case_srcdir)/tests/venv/bin/activate \
91+
&& python3 src/ontology_and_version_iris.py \
92+
_$@ \
93+
case-*.ttl
94+
mv _$@ $@
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env python3
2+
3+
# This software was developed at the National Institute of Standards
4+
# and Technology by employees of the Federal Government in the course
5+
# of their official duties. Pursuant to title 17 Section 105 of the
6+
# United States Code this software is not subject to copyright
7+
# protection and is in the public domain. NIST assumes no
8+
# responsibility whatsoever for its use by other parties, and makes
9+
# no guarantees, expressed or implied, about its quality,
10+
# reliability, or any other characteristic.
11+
#
12+
# We would appreciate acknowledgement if the software is used.
13+
14+
"""
15+
This script creates a list of all ontology and version IRIs that have ever existed in a CDO ontology to describe a CDO ontology. I.e. the subject of triples with owl:Ontology as predicate are included, as are the objects of version-referencing triples (owl:versionIRI, owl:incompatibleWith, etc.).
16+
"""
17+
18+
__version__ = "0.1.0"
19+
20+
import argparse
21+
import typing
22+
23+
import rdflib
24+
25+
NS_OWL = rdflib.OWL
26+
NS_RDF = rdflib.RDF
27+
28+
29+
def concept_is_cdo_concept(n_concept: rdflib.URIRef) -> bool:
30+
"""
31+
This function is purposefully distinct from the function used in case_validate. Within this script, the publishing history of CASE and UCO is reviewed."""
32+
concept_iri = str(n_concept)
33+
return (
34+
concept_iri.startswith("https://ontology.unifiedcyberontology.org/")
35+
or concept_iri.startswith("https://ontology.caseontology.org/")
36+
or concept_iri.startswith("https://unifiedcyberontology.org/ontology/")
37+
or concept_iri.startswith("https://caseontology.org/ontology/")
38+
or concept_iri == "http://case.example.org/core"
39+
)
40+
41+
42+
def extract_ontology_iris(ontology_graph: rdflib.Graph) -> typing.Set[rdflib.URIRef]:
43+
"""
44+
Return all concepts describing the OWL Ontology in the input graph. This does not return classes, properties, etc. defined within the ontology; instead, it only returns the ontology IRI and annotations about the ontology.
45+
"""
46+
ontology_concepts: typing.Set[rdflib.URIRef] = set()
47+
for n_ontology_predicate in [
48+
NS_OWL.backwardCompatibleWith,
49+
NS_OWL.imports,
50+
NS_OWL.incompatibleWith,
51+
NS_OWL.priorVersion,
52+
NS_OWL.versionIRI,
53+
]:
54+
for ontology_triple in ontology_graph.triples(
55+
(None, n_ontology_predicate, None)
56+
):
57+
assert isinstance(ontology_triple[0], rdflib.URIRef)
58+
assert isinstance(ontology_triple[2], rdflib.URIRef)
59+
ontology_concepts.add(ontology_triple[0])
60+
ontology_concepts.add(ontology_triple[2])
61+
for ontology_triple in ontology_graph.triples((None, NS_RDF.type, NS_OWL.Ontology)):
62+
if not isinstance(ontology_triple[0], rdflib.URIRef):
63+
continue
64+
if concept_is_cdo_concept(ontology_triple[0]):
65+
ontology_concepts.add(ontology_triple[0])
66+
return ontology_concepts
67+
68+
69+
def main() -> None:
70+
parser = argparse.ArgumentParser()
71+
parser.add_argument("out_txt")
72+
parser.add_argument("in_ttl", nargs="+")
73+
args = parser.parse_args()
74+
75+
cdo_concepts: typing.Set[rdflib.URIRef] = set()
76+
for in_ttl in args.in_ttl:
77+
ontology_graph = rdflib.Graph()
78+
ontology_graph.parse(in_ttl)
79+
ontology_concepts = extract_ontology_iris(ontology_graph)
80+
for ontology_concept in ontology_concepts:
81+
if concept_is_cdo_concept(ontology_concept):
82+
cdo_concepts.add(ontology_concept)
83+
84+
with open(args.out_txt, "w") as out_fh:
85+
for cdo_concept in sorted(cdo_concepts):
86+
print(cdo_concept, file=out_fh)
87+
88+
89+
if __name__ == "__main__":
90+
main()

tests/case_utils/case_validate/cli/Makefile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ files_to_generate := \
4242
format_unspecified_output_turtle.ttl \
4343
format_unspecified_output_txt.txt \
4444
format_unspecified_output_unspecified.txt \
45+
past_version_reference_PASS.txt \
46+
past_version_reference_XFAIL.txt \
4547
split_data_graph_PASS.txt \
4648
split_data_graph_XFAIL.txt \
4749
thing_metashacl_PASS.txt
@@ -220,6 +222,36 @@ format_unspecified_output_unspecified.txt: \
220222
> _$@
221223
mv _$@ $@
222224

225+
past_version_reference_PASS.txt: \
226+
$(tests_srcdir)/.venv.done.log \
227+
$(top_srcdir)/.ontology.done.log \
228+
$(top_srcdir)/case_utils/case_validate/__init__.py \
229+
$(top_srcdir)/case_utils/ontology/__init__.py \
230+
$(top_srcdir)/case_utils/ontology/ontology_and_version_iris.txt \
231+
past_version_reference_PASS.ttl
232+
rm -f _$@
233+
source $(tests_srcdir)/venv/bin/activate \
234+
&& case_validate \
235+
past_version_reference_PASS.ttl \
236+
> _$@
237+
mv _$@ $@
238+
239+
past_version_reference_XFAIL.txt: \
240+
$(tests_srcdir)/.venv.done.log \
241+
$(top_srcdir)/.ontology.done.log \
242+
$(top_srcdir)/case_utils/case_validate/__init__.py \
243+
$(top_srcdir)/case_utils/ontology/__init__.py \
244+
$(top_srcdir)/case_utils/ontology/ontology_and_version_iris.txt \
245+
past_version_reference_XFAIL.ttl
246+
rm -f _$@
247+
source $(tests_srcdir)/venv/bin/activate \
248+
&& case_validate \
249+
past_version_reference_XFAIL.ttl \
250+
> _$@ \
251+
; rc=$$? ; test 1 -eq $$rc
252+
test -s _$@
253+
mv _$@ $@
254+
223255
split_data_graph_PASS.txt: \
224256
$(tests_srcdir)/.venv.done.log \
225257
$(top_srcdir)/.ontology.done.log \
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
2+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
3+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
4+
@prefix uco-core: <https://ontology.unifiedcyberontology.org/uco/core/> .
5+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
6+
7+
<urn:example:thing-a5ba4c5b-9e12-41e8-b05d-4dfb0dd61ec3>
8+
a uco-core:UcoThing ;
9+
rdfs:comment "This node maintains a historic reference to 0.9.1 of the UCO namespace. This must not trigger an undefined-concept warning."@en ;
10+
rdfs:seeAlso uco-core:0.9.1 ;
11+
.
12+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
2+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
3+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
4+
@prefix uco-core: <https://ontology.unifiedcyberontology.org/uco/core/> .
5+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
6+
7+
<urn:example:thing-bcd908d5-d89b-4352-afe0-190ce331fd5b>
8+
a uco-core:UcoThing ;
9+
rdfs:comment "This node references a never-published UCO Core namespace version. This is expected to trigger a warning."@en ;
10+
rdfs:seeAlso uco-core:0.0.1 ;
11+
.
12+

0 commit comments

Comments
 (0)