From 5a80146ab0501dae750c5cb2cd2b167ab26a24be Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 30 Jul 2024 09:13:48 -0400 Subject: [PATCH 1/2] Add Non/InformationResource A follow-on patch will regenerate Make-managed files. References: * https://github.com/ucoProject/UCO/issues/619 Signed-off-by: Alex Nelson --- ontology/uco/action/action.ttl | 5 +- ontology/uco/core/core.ttl | 46 +++++++++++- ontology/uco/identity/identity.ttl | 10 ++- ontology/uco/observable/observable.ttl | 26 ++++++- tests/examples/Makefile | 2 + tests/examples/information_resource_PASS.json | 74 +++++++++++++++++++ tests/examples/test_validation.py | 13 ++++ 7 files changed, 168 insertions(+), 8 deletions(-) create mode 100644 tests/examples/information_resource_PASS.json diff --git a/ontology/uco/action/action.ttl b/ontology/uco/action/action.ttl index 17698eec..5dabd5ad 100644 --- a/ontology/uco/action/action.ttl +++ b/ontology/uco/action/action.ttl @@ -37,7 +37,10 @@ action:Action owl:Class , sh:NodeShape ; - rdfs:subClassOf core:UcoObject ; + rdfs:subClassOf + core:NeverInformationResource , + core:UcoObject + ; rdfs:label "Action"@en ; rdfs:comment "An action is something that may be done or performed."@en ; owl:disjointWith core:Event ; diff --git a/ontology/uco/core/core.ttl b/ontology/uco/core/core.ttl index 8bd191fb..1b9e83f2 100644 --- a/ontology/uco/core/core.ttl +++ b/ontology/uco/core/core.ttl @@ -181,7 +181,10 @@ core:Event owl:Class , sh:NodeShape ; - rdfs:subClassOf core:UcoObject ; + rdfs:subClassOf + core:NeverInformationResource , + core:UcoObject + ; rdfs:label "Event"@en ; rdfs:comment "An Event is a noteworthy occurrence (something that happens or might happen)."@en ; owl:disjointWith action:Action ; @@ -284,6 +287,27 @@ core:IdentityAbstraction sh:targetClass core:IdentityAbstraction ; . +core:InformationResource + a + owl:Class , + sh:NodeShape + ; + rdfs:subClassOf core:UcoThing ; + owl:disjointWith core:NeverInformationResource ; + sh:targetClass core:InformationResource ; + . + +core:InformationResource-disjointWith-NeverInformationResource-shape + a sh:NodeShape ; + sh:message "core:InformationResource and core:NeverInformationResource are disjoint classes. Assigning both types to a single node will be an error as of UCO 2.0.0."@en ; + sh:not [ + a sh:NodeShape ; + sh:class core:NeverInformationResource ; + ] ; + sh:severity sh:Warning ; + sh:targetClass core:InformationResource ; + . + core:Item a owl:Class , @@ -317,6 +341,24 @@ core:ModusOperandi sh:targetClass core:ModusOperandi ; . +core:NeverInformationResource + a + owl:Class , + sh:NodeShape + ; + rdfs:subClassOf core:NonInformationResource ; + sh:targetClass core:NeverInformationResource ; + . + +core:NonInformationResource + a + owl:Class , + sh:NodeShape + ; + rdfs:subClassOf core:UcoThing ; + sh:targetClass core:NonInformationResource ; + . + core:Relationship a owl:Class , @@ -371,7 +413,7 @@ core:UcoInherentCharacterizationThing owl:Class , sh:NodeShape ; - rdfs:subClassOf core:UcoThing ; + rdfs:subClassOf core:NeverInformationResource ; rdfs:label "UcoInherentCharacterizationThing"@en ; rdfs:comment "A UCO inherent characterization thing is a grouping of characteristics unique to a particular inherent aspect of a UCO domain object."@en ; sh:targetClass core:UcoInherentCharacterizationThing ; diff --git a/ontology/uco/identity/identity.ttl b/ontology/uco/identity/identity.ttl index 93c20b6f..06df8e18 100644 --- a/ontology/uco/identity/identity.ttl +++ b/ontology/uco/identity/identity.ttl @@ -160,7 +160,10 @@ identity:Organization owl:Class , sh:NodeShape ; - rdfs:subClassOf identity:Identity ; + rdfs:subClassOf + core:NeverInformationResource , + identity:Identity + ; rdfs:label "Organization"@en ; rdfs:comment "An organization is a grouping of identifying characteristics unique to a group of people who work together in an organized way for a shared purpose. [based on https://dictionary.cambridge.org/us/dictionary/english/organization]"@en ; sh:targetClass identity:Organization ; @@ -182,7 +185,10 @@ identity:Person owl:Class , sh:NodeShape ; - rdfs:subClassOf identity:Identity ; + rdfs:subClassOf + core:NeverInformationResource , + identity:Identity + ; rdfs:label "Person"@en ; rdfs:comment "A person is a grouping of identifying characteristics unique to a human being regarded as an individual. [based on https://www.lexico.com/en/definition/person]"@en ; sh:targetClass identity:Person ; diff --git a/ontology/uco/observable/observable.ttl b/ontology/uco/observable/observable.ttl index 37dc84be..7526e0e1 100644 --- a/ontology/uco/observable/observable.ttl +++ b/ontology/uco/observable/observable.ttl @@ -2221,7 +2221,10 @@ observable:Device owl:Class , sh:NodeShape ; - rdfs:subClassOf observable:ObservableObject ; + rdfs:subClassOf + core:NeverInformationResource , + observable:ObservableObject + ; rdfs:label "Device"@en ; rdfs:comment "A device is a piece of equipment or a mechanism designed to serve a special purpose or perform a special function. [based on https://www.merriam-webster.com/dictionary/device]"@en ; sh:targetClass observable:Device ; @@ -6903,7 +6906,10 @@ observable:URL owl:Class , sh:NodeShape ; - rdfs:subClassOf observable:ObservableObject ; + rdfs:subClassOf + core:NeverInformationResource , + observable:ObservableObject + ; rdfs:label "URL"@en ; rdfs:comment "A URL is a uniform resource locator (URL) acting as a resolvable address to a particular WWW (World Wide Web) accessible resource."@en ; sh:targetClass observable:URL ; @@ -7359,12 +7365,26 @@ observable:WebPage owl:Class , sh:NodeShape ; - rdfs:subClassOf observable:ObservableObject ; + rdfs:subClassOf + core:InformationResource , + observable:WebResource + ; rdfs:label "WebPage"@en ; rdfs:comment "A web page is a specific collection of information provided by a website and displayed to a user in a web browser. A website typically consists of many web pages linked together in a coherent fashion. [based on https://en.wikipedia.org/wiki/Web_page]"@en ; sh:targetClass observable:WebPage ; . +observable:WebResource + a + owl:Class , + sh:NodeShape + ; + rdfs:subClassOf observable:ObservableObject ; + rdfs:label "WebResource"@en ; + rdfs:seeAlso ; + sh:targetClass observable:WebResource ; + . + observable:WhoIs a owl:Class , diff --git a/tests/examples/Makefile b/tests/examples/Makefile index 66b33e05..c75d7cc1 100644 --- a/tests/examples/Makefile +++ b/tests/examples/Makefile @@ -37,6 +37,7 @@ all: \ has_facet_inverse_functional_XFAIL_validation.ttl \ hash_PASS_validation.ttl \ hash_XFAIL_validation.ttl \ + information_resource_PASS_validation.ttl \ location_PASS_validation.ttl \ location_XFAIL_validation.ttl \ message_thread_PASS_validation.ttl \ @@ -112,6 +113,7 @@ check: \ has_facet_inverse_functional_XFAIL_validation.ttl \ hash_PASS_validation.ttl \ hash_XFAIL_validation.ttl \ + information_resource_PASS_validation.ttl \ location_PASS_validation.ttl \ location_XFAIL_validation.ttl \ message_thread_PASS_validation.ttl \ diff --git a/tests/examples/information_resource_PASS.json b/tests/examples/information_resource_PASS.json new file mode 100644 index 00000000..12af7bbf --- /dev/null +++ b/tests/examples/information_resource_PASS.json @@ -0,0 +1,74 @@ +{ + "@context": { + "core": "https://ontology.unifiedcyberontology.org/uco/core/", + "kb": "http://example.org/kb/", + "identity": "https://ontology.unifiedcyberontology.org/uco/identity/", + "observable": "https://ontology.unifiedcyberontology.org/uco/observable/", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#" + }, + "@graph": [ + { + "@id": "http://example.org/~bob", + "@type": [ + "identity:Person", + "observable:WebPage" + ], + "core:name": "Bob", + "core:description": "Bob's company home page.", + "rdfs:comment": "This node will trigger a warning from conflating a node as both a person and the person's home page.", + "rdfs:seeAlso": [ + { + "@id": "kb:Person-a3d3af3d-ea1d-47f6-bc02-ac334ded6549" + }, + { + "@id": "kb:WebPage-1c05c378-124e-4d3c-898a-fb5a8d178cf8" + } + ] + }, + { + "@id": "kb:Person-a3d3af3d-ea1d-47f6-bc02-ac334ded6549", + "@type": "identity:Person", + "core:name": "Bob", + "rdfs:seeAlso": { + "@id": "http://example.org/~bob" + } + }, + { + "@id": "kb:WebPage-1c05c378-124e-4d3c-898a-fb5a8d178cf8", + "@type": "observable:WebPage", + "core:description": "Bob's company home page.", + "rdfs:seeAlso": { + "@id": "http://example.org/~bob" + } + }, + { + "@id": "http://example.org/~chris", + "@type": "observable:WebResource", + "rdfs:comment": "This node will trigger an info-level result from not designating itself a InformationResource, and not ending with a UUID." + }, + { + "@id": "https://mc.example.co.jp/", + "@type": "observable:WebPage", + "rdfs:comment": [ + "This node should trigger no errors, even when incorporating the annotations on the same identifier from another JSON dict.", + "This JSON dict was provided by a market analyst in Japan." + ] + }, + { + "@id": "https://mc.example.co.jp/", + "@type": ["core:NonInformationResource", "observable:WebResource"], + "rdfs:comment": [ + "This node should trigger no errors, even when incorporating the annotations on the same identifier from another JSON dict.", + "This JSON dict was provided by a market analyst in France." + ] + }, + { + "@id": "https://mc.example.co.jp/lang-fr/", + "@type": "observable:WebPage", + "rdfs:comment": [ + "This node should trigger no errors.", + "This JSON dict was provided by a market analyst in France." + ] + } + ] +} diff --git a/tests/examples/test_validation.py b/tests/examples/test_validation.py index 6c4fc658..94a5fd32 100644 --- a/tests/examples/test_validation.py +++ b/tests/examples/test_validation.py @@ -299,6 +299,19 @@ def test_hash_XFAIL() -> None: } ) +def test_information_resource_PASS_validation() -> None: + confirm_validation_results( + "information_resource_PASS_validation.ttl", + True, + expected_focus_node_severities={ + ("http://example.org/~bob", str(NS_SH.Warning)), + ("http://example.org/~bob", str(NS_SH.Info)), + ("http://example.org/~chris", str(NS_SH.Info)), + ("https://mc.example.co.jp/", str(NS_SH.Info)), + ("https://mc.example.co.jp/lang-fr/", str(NS_SH.Info)), + } + ) + def test_co_PASS_validation() -> None: confirm_validation_results("co_PASS_validation.ttl", True) From c20520579fa66f6da5a9210a5caad088e70ef074 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Tue, 30 Jul 2024 09:25:09 -0400 Subject: [PATCH 2/2] Regenerate Make-managed files References: * https://github.com/ucoProject/UCO/issues/619 Signed-off-by: Alex Nelson --- .../information_resource_PASS_validation.ttl | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 tests/examples/information_resource_PASS_validation.ttl diff --git a/tests/examples/information_resource_PASS_validation.ttl b/tests/examples/information_resource_PASS_validation.ttl new file mode 100644 index 00000000..3f0c4691 --- /dev/null +++ b/tests/examples/information_resource_PASS_validation.ttl @@ -0,0 +1,139 @@ +@prefix core: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + +[] + a sh:ValidationReport ; + sh:conforms "true"^^xsd:boolean ; + sh:result + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "UcoThings are suggested to end with a UUID." ; + sh:resultSeverity sh:Info ; + sh:sourceConstraint [ + a sh:SPARQLConstraint ; + rdfs:seeAlso ; + sh:message "UcoThings are suggested to end with a UUID."@en ; + sh:select ''' + PREFIX rdfs: + PREFIX core: + SELECT $this + WHERE { + $this a/rdfs:subClassOf* core:UcoThing . + FILTER ( + ! REGEX ( + STR($this), + "[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$", + "i" + ) + ) + } + ''' ; + ] ; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent ; + sh:sourceShape core:UcoThing-identifier-regex-shape ; + sh:value ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "core:InformationResource and core:NeverInformationResource are disjoint classes. Assigning both types to a single node will be an error as of UCO 2.0.0."@en ; + sh:resultSeverity sh:Warning ; + sh:sourceConstraintComponent sh:NotConstraintComponent ; + sh:sourceShape core:InformationResource-disjointWith-NeverInformationResource-shape ; + sh:value ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "UcoThings are suggested to end with a UUID." ; + sh:resultSeverity sh:Info ; + sh:sourceConstraint [ + a sh:SPARQLConstraint ; + rdfs:seeAlso ; + sh:message "UcoThings are suggested to end with a UUID."@en ; + sh:select ''' + PREFIX rdfs: + PREFIX core: + SELECT $this + WHERE { + $this a/rdfs:subClassOf* core:UcoThing . + FILTER ( + ! REGEX ( + STR($this), + "[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$", + "i" + ) + ) + } + ''' ; + ] ; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent ; + sh:sourceShape core:UcoThing-identifier-regex-shape ; + sh:value ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "UcoThings are suggested to end with a UUID." ; + sh:resultSeverity sh:Info ; + sh:sourceConstraint [ + a sh:SPARQLConstraint ; + rdfs:seeAlso ; + sh:message "UcoThings are suggested to end with a UUID."@en ; + sh:select ''' + PREFIX rdfs: + PREFIX core: + SELECT $this + WHERE { + $this a/rdfs:subClassOf* core:UcoThing . + FILTER ( + ! REGEX ( + STR($this), + "[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$", + "i" + ) + ) + } + ''' ; + ] ; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent ; + sh:sourceShape core:UcoThing-identifier-regex-shape ; + sh:value ; + ] , + [ + a sh:ValidationResult ; + sh:focusNode ; + sh:resultMessage "UcoThings are suggested to end with a UUID." ; + sh:resultSeverity sh:Info ; + sh:sourceConstraint [ + a sh:SPARQLConstraint ; + rdfs:seeAlso ; + sh:message "UcoThings are suggested to end with a UUID."@en ; + sh:select ''' + PREFIX rdfs: + PREFIX core: + SELECT $this + WHERE { + $this a/rdfs:subClassOf* core:UcoThing . + FILTER ( + ! REGEX ( + STR($this), + "[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$", + "i" + ) + ) + } + ''' ; + ] ; + sh:sourceConstraintComponent sh:SPARQLConstraintComponent ; + sh:sourceShape core:UcoThing-identifier-regex-shape ; + sh:value ; + ] + ; + . +