Skip to content

Commit

Permalink
Merge branch 'Feature-Issue-602-NewDictionaries' into unstable
Browse files Browse the repository at this point in the history
  • Loading branch information
ajnelson-nist committed Jun 5, 2024
2 parents 0a6de6f + 6d4b850 commit c8c5871
Show file tree
Hide file tree
Showing 8 changed files with 499 additions and 114 deletions.
123 changes: 100 additions & 23 deletions ontology/uco/types/types.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -59,37 +59,47 @@ types:Dictionary
;
rdfs:subClassOf core:UcoInherentCharacterizationThing ;
rdfs:label "Dictionary"@en ;
rdfs:comment "A dictionary is list of (term/key, value) pairs with each term/key existing no more than once."@en ;
rdfs:seeAlso [
a sh:NodeShape ;
rdfs:comment "This anonymous shape is attached to types:Dictionary with rdfs:seeAlso in order to associate a warning-severity SPARQL-based shape, that will only be necessary as an independent shape until UCO 2.0.0."@en ;
sh:severity sh:Warning ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A key in a dictionary can appear no more than once."@en ;
sh:select """
PREFIX types: <https://ontology.unifiedcyberontology.org/uco/types/>
SELECT $this ?value
WHERE {
$this
types:entry/types:key ?value ;
.
}
GROUP BY ?value
HAVING (COUNT(?value) > 1)
""" ;
] ;
sh:targetClass types:Dictionary ;
] ;
rdfs:comment "A dictionary is list of (term/key, value) pairs with each term/key having an expectation to exist no more than once. types:Dictionary alone does not validate this expectation, but validation is available. For use cases where this expectation must be validated, the subclass types:ProperDictionary should be used instead of types:Dictionary. For instances where this expectation has been found to be violated, the subclass types:ImproperDictionary should be used instead of types:Dictionary."@en ;
sh:property [
sh:class types:DictionaryEntry ;
sh:minCount "1"^^xsd:integer ;
sh:nodeKind sh:IRI ;
sh:path types:entry ;
] ;
sh:targetClass types:Dictionary ;
.

types:Dictionary-keyUniqueness-shape
a sh:NodeShape ;
sh:description "This shape is separated from the types:Dictionary class-shape in order to associate a warning-severity SPARQL-based shape."@en ;
sh:severity sh:Warning ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A key in a dictionary should appear no more than once. The value literal does. Please consider using the types:ImproperDictionary class and types:repeatsKey property."@en ;
sh:select """
PREFIX types: <https://ontology.unifiedcyberontology.org/uco/types/>
SELECT $this ?value
WHERE {
$this
types:entry/types:key ?value ;
.
FILTER NOT EXISTS {
$this
a types:ImproperDictionary ;
.
}
FILTER NOT EXISTS {
$this
a types:ProperDictionary ;
.
}
}
GROUP BY ?value
HAVING (COUNT(?value) > 1)
""" ;
] ;
sh:targetClass types:Dictionary ;
.

types:DictionaryEntry
a
owl:Class ,
Expand Down Expand Up @@ -188,11 +198,64 @@ types:Identifier
rdfs:comment "An identifier is a string conformant to the specified UUID-based format for UCO object identifiers."@en ;
.

types:ImproperDictionary
a
owl:Class ,
sh:NodeShape
;
rdfs:subClassOf types:Dictionary ;
rdfs:label "ImproperDictionary"@en ;
owl:disjointWith types:ProperDictionary ;
sh:property [
sh:datatype xsd:string ;
sh:nodeKind sh:Literal ;
sh:path types:repeatsKey ;
] ;
sh:targetClass types:ImproperDictionary ;
.

types:ImproperDictionary-disjointWith-ProperDictionary-shape
a sh:NodeShape ;
sh:message "types:ImproperDictionary and types:ProperDictionary are disjoint classes."@en ;
sh:not [
a sh:NodeShape ;
sh:class types:ProperDictionary ;
] ;
sh:targetClass types:ImproperDictionary ;
.

types:NativeFormatString
a rdfs:Datatype ;
rdfs:comment "Specifies data in its native format of some external language. The data may be encoded in Base64 per [RFC4648]. Data encoded in Base64 must be denoted as such using the encoded property."@en ;
.

types:ProperDictionary
a
owl:Class ,
sh:NodeShape
;
rdfs:subClassOf types:Dictionary ;
rdfs:label "ProperDictionary"@en ;
rdfs:comment "A proper dictionary is list of (term/key, value) pairs with each term/key existing no more than once."@en ;
owl:disjointWith types:ImproperDictionary ;
sh:sparql [
a sh:SPARQLConstraint ;
sh:message "A key in a proper dictionary can appear no more than once."@en ;
sh:select """
PREFIX types: <https://ontology.unifiedcyberontology.org/uco/types/>
SELECT $this ?value
WHERE {
$this
types:entry/types:key ?value ;
.
}
GROUP BY ?value
HAVING (COUNT(?value) > 1)
""" ;
] ;
sh:targetClass types:ProperDictionary ;
.

types:StructuredText
a rdfs:Datatype ;
rdfs:comment "Expresses string-based data in some information structuring format (e.g., HTML5)."@en ;
Expand Down Expand Up @@ -290,6 +353,20 @@ types:key
rdfs:range xsd:string ;
.

types:repeatsKey
a owl:DatatypeProperty ;
rdfs:label "repeatsKey"@en ;
rdfs:comment "A key found to be repeated in multiple dictionary entries within one dictionary."@en ;
rdfs:domain types:ImproperDictionary ;
rdfs:range xsd:string ;
.

types:repeatsKey-subjects-shape
a sh:NodeShape ;
sh:class types:ImproperDictionary ;
sh:targetSubjectsOf types:repeatsKey ;
.

types:threadNextItem
a owl:ObjectProperty ;
rdfs:subPropertyOf types:threadSuccessor ;
Expand Down
2 changes: 2 additions & 0 deletions tests/examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ all: \
database_records_PASS_validation.ttl \
database_records_XFAIL_validation.ttl \
dictionary_PASS_validation.ttl \
dictionary_XFAIL_validation.ttl \
disjointedness_PASS_validation.ttl \
event_XFAIL_validation.ttl \
file_url_PASS_validation.ttl \
Expand Down Expand Up @@ -105,6 +106,7 @@ check: \
database_records_PASS_validation.ttl \
database_records_XFAIL_validation.ttl \
dictionary_PASS_validation.ttl \
dictionary_XFAIL_validation.ttl \
disjointedness_PASS_validation.ttl \
event_XFAIL_validation.ttl \
file_url_PASS_validation.ttl \
Expand Down
26 changes: 26 additions & 0 deletions tests/examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,32 @@ Two instance data files are currently in the directory:
SHACL validation results are stored in corresponding files named `..._validation.ttl`, to present the current state of validation conditions.


## Design of the Dictionary tests

The `Dictionary` objects in the `dictionary_*.json` files cover these combinations of asserted type (proper dictionary, improper dictionary, or the generic parent class), whether a dictionary entry key is repeated in the data, and whether the `repeatsKey` property is asserted. (P/X denotes whether the instance is a PASS or XFAIL test case.)

| uuid | P/X | Dictionary type | Key repeats | repeatsKey asserted |
| --- | --- | --- | --- | --- |
| `3bb38b3e` | P | `Dictionary` | no | no |
| `e6dc9c2e` | X | `Dictionary` | no | yes |
| `e9adf6c1` | P | `Dictionary` | yes | no |
| `34ac0c49` | X | `Dictionary` | yes | yes |
| `cbc1c80d` | P | `ImproperDictionary` | no | no |
| `7fa3ea45` | P | `ImproperDictionary` | no | yes |
| `14e28425` | P | `ImproperDictionary` | yes | no |
| `a8e5e8e1` | P | `ImproperDictionary` | yes | yes |
| `eaded28e` | P | `ProperDictionary` | no | no |
| `8114819f` | X | `ProperDictionary` | no | yes |
| `b2baf8af` | X | `ProperDictionary` | yes | no |
| `f5ae2e6a` | X | `ProperDictionary` | yes | yes |

Other miscellaneous tests are added without full combinatoric review:

* `kb:ProperDictionary-f5ae2e6a-9b10-46f3-8441-30aada36aa1b` also demonstrates an XFAIL case where a key-value *pair* is repeated.
* `kb:ImproperDictionary-7fa3ea45-6426-4ad3-bb5f-7559e07adeb4` also demonstrates a PASS case where `repeatsKey`'s value is not in the supplied dictionary.
* `kb:Dictionary-5bc55661-4808-48e6-9e02-80a153eee5d3` demonstrates an XFAIL case where the disjoint `Dictionary` subtypes are both asserted.


## Design of the Relationship tests

The `Relationship` objects in the `relationship_*.json` files include a numbering scheme in their identifiers, (object class)-(lexical value)-(datatype). These track the following matrix of test cases:
Expand Down
71 changes: 65 additions & 6 deletions tests/examples/dictionary_PASS.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,26 @@
},
"@graph": [
{
"@id": "kb:Dictionary-eaded28e-0bf8-4df1-aee8-84d22c09702c",
"@id": "kb:Dictionary-3bb38b3e-d47a-43c8-8a77-afc0e6655ce1",
"@type": "types:Dictionary",
"types:entry": [
{
"@id": "kb:DictionaryEntry-b8a01d49-53c1-440f-a2d5-618b58801d37",
"@type": "types:DictionaryEntry",
"types:key": "x",
"types:value": "1"
},
{
"@id": "kb:DictionaryEntry-6cac6c2c-5d4e-45f5-b784-c029c9f9fb6d",
"@type": "types:DictionaryEntry",
"types:key": "y",
"types:value": "2"
}
]
},
{
"@id": "kb:ProperDictionary-eaded28e-0bf8-4df1-aee8-84d22c09702c",
"@type": "types:ProperDictionary",
"types:entry": [
{
"@id": "kb:DictionaryEntry-314212eb-39c4-4bf3-be3a-f07c38f0eae8",
Expand All @@ -24,9 +42,9 @@
]
},
{
"@id": "kb:Dictionary-a8e5e8e1-b3de-4ac4-99dd-e36f96beea4d",
"@type": "types:Dictionary",
"rdfs:comment": "This dictionary will trigger a warning from having two entries keyed with value 'x'.",
"@id": "kb:ImproperDictionary-a8e5e8e1-b3de-4ac4-99dd-e36f96beea4d",
"@type": "types:ImproperDictionary",
"types:repeatsKey": "x",
"types:entry": [
{
"@id": "kb:DictionaryEntry-55786f64-534d-4e8c-8a64-616f708ea4d3",
Expand All @@ -44,9 +62,8 @@
},
{
"@id": "kb:Dictionary-e9adf6c1-0287-4290-95a9-c94a128d7ff6",

"@type": "types:Dictionary",
"rdfs:comment": "This dictionary will trigger a warning from having two entries keyed with value 'x'.",
"rdfs:comment": "This dictionary, not being typed as a ProperDictionary, will not trigger a warning from having two entries keyed with value 'x'.",
"types:entry": [
{
"@id": "kb:DictionaryEntry-20431f00-64a3-4c0f-94a4-1eb09f8a6b6a",
Expand All @@ -61,6 +78,48 @@
"types:value": "1"
}
]
},
{
"@id": "kb:ImproperDictionary-7fa3ea45-6426-4ad3-bb5f-7559e07adeb4",
"@type": "types:ImproperDictionary",
"repeatsKey": "z"
},
{
"@id": "kb:ImproperDictionary-14e28425-00c1-4f11-b2ed-21390fc0749a",
"@type": "types:ImproperDictionary",
"types:entry": [
{
"@id": "kb:DictionaryEntry-09f23642-389b-4553-b5be-283a6160f534",
"@type": "types:DictionaryEntry",
"types:key": "x",
"types:value": "1"
},
{
"@id": "kb:DictionaryEntry-7a84a0d6-d1cd-4291-afb4-c834d611898d",
"@type": "types:DictionaryEntry",
"types:key": "x",
"types:value": "2"
}
]
},
{
"@id": "kb:ImproperDictionary-cbc1c80d-1bad-4947-8459-c53ff61e8bfa",
"@type": "types:ImproperDictionary",
"rdfs:comment": "This improper dictionary has no repeated key or assertion of a repeated key. This should not trigger a data error, because the information in the graph could merely be incomplete.",
"types:entry": [
{
"@id": "kb:DictionaryEntry-ca1910ab-fa26-402a-86bb-229f490dd89a",
"@type": "types:DictionaryEntry",
"types:key": "x",
"types:value": "1"
},
{
"@id": "kb:DictionaryEntry-2a13e674-5e95-4a7a-9fac-c90417dcd97c",
"@type": "types:DictionaryEntry",
"types:key": "y",
"types:value": "2"
}
]
}
]
}
Loading

0 comments on commit c8c5871

Please sign in to comment.