From af311192616015fd4041540912cb5226e3156e94 Mon Sep 17 00:00:00 2001 From: Alex Nelson Date: Fri, 15 Dec 2023 16:47:53 -0500 Subject: [PATCH] Create joint investigation assuming Investigation as Event and Perdurant This patch is exploratory. A follow-on patch will regenerate Make-managed files. References: * https://github.com/casework/CASE/issues/138 * https://github.com/ucoProject/UCO/issues/544 Signed-off-by: Alex Nelson --- .../src/crossover_heist-supplemental.json | 4 + examples/crossover_linked/.gitignore | 1 + examples/crossover_linked/Makefile | 93 ++++++ .../crossover_linked/crossover_linked.json | 137 ++++++++ examples/crossover_linked/drafting.ttl | 307 ++++++++++++++++++ .../query-email_addresses_in_common.sparql | 20 ++ .../src/crossover_wmd-email.json | 4 +- .../src/crossover_wmd-supplemental.json | 10 + 8 files changed, 575 insertions(+), 1 deletion(-) create mode 100644 examples/crossover_linked/.gitignore create mode 100644 examples/crossover_linked/Makefile create mode 100644 examples/crossover_linked/crossover_linked.json create mode 100644 examples/crossover_linked/drafting.ttl create mode 100644 examples/crossover_linked/query-email_addresses_in_common.sparql create mode 100644 examples/crossover_wmd/src/crossover_wmd-supplemental.json diff --git a/examples/crossover_heist/src/crossover_heist-supplemental.json b/examples/crossover_heist/src/crossover_heist-supplemental.json index 39d79b50..4693723d 100644 --- a/examples/crossover_heist/src/crossover_heist-supplemental.json +++ b/examples/crossover_heist/src/crossover_heist-supplemental.json @@ -14,5 +14,9 @@ "@type": "xsd:hexBinary", "@value": "a1ecc7523855f23f3f9a96e3ec0f53ece109cd7d" } + }, + { + "@id": "kb:EmailAccount-ca4bc5e3-33a7-4457-b106-d0213e248979", + "rdfs:comment": "TODO - Discuss." } ] diff --git a/examples/crossover_linked/.gitignore b/examples/crossover_linked/.gitignore new file mode 100644 index 00000000..11f83096 --- /dev/null +++ b/examples/crossover_linked/.gitignore @@ -0,0 +1 @@ +*.validates.log diff --git a/examples/crossover_linked/Makefile b/examples/crossover_linked/Makefile new file mode 100644 index 00000000..1c2ddf0d --- /dev/null +++ b/examples/crossover_linked/Makefile @@ -0,0 +1,93 @@ +#!/usr/bin/make -f + +# Portions of this file contributed by NIST are governed by the +# following statement: +# +# This software was developed at the National Institute of Standards +# and Technology by employees of the Federal Government in the course +# of their official duties. Pursuant to Title 17 Section 105 of the +# United States Code, this software is not subject to copyright +# protection within the United States. NIST assumes no responsibility +# whatsoever for its use by other parties, and makes no guarantees, +# expressed or implied, about its quality, reliability, or any other +# characteristic. +# +# We would appreciate acknowledgement if the software is used. + +# Implementation note: +# During exploratory development, this Makefile does not yet fit the +# workflow of the other examples, mainly because other example graphs +# are needed to review queries. + +SHELL := /bin/bash + +top_srcdir := $(shell cd ../.. ; pwd) + +RDF_TOOLKIT_JAR := $(top_srcdir)/dependencies/CASE-develop/dependencies/UCO/lib/rdf-toolkit.jar + +all: \ + query-email_addresses_in_common.html + +.drafting.ttl.validates.log: \ + $(top_srcdir)/.venv.done.log \ + drafting.ttl + source $(top_srcdir)/venv/bin/activate \ + && case_validate \ + --abort \ + --inference none \ + --metashacl \ + --review-tbox \ + drafting.ttl + touch $@ + +check: \ + all + +clean: + @rm -f \ + .drafting.ttl.validates.log \ + *validation*.ttl + +crossover_linked_validation.ttl: \ + $(RDF_TOOLKIT_JAR) \ + ../crossover_heist/crossover_heist.json \ + ../crossover_wmd/crossover_wmd.json \ + .drafting.ttl.validates.log \ + crossover_linked.json + rm -f __$@ _$@ + source $(top_srcdir)/venv/bin/activate \ + && case_validate \ + --abort \ + --allow-infos \ + --format turtle \ + --inference none \ + --ontology-graph drafting.ttl \ + --output __$@ \ + ../crossover_heist/crossover_heist.json \ + ../crossover_wmd/crossover_wmd.json \ + crossover_linked.json + test -s __$@ + java -jar $(RDF_TOOLKIT_JAR) \ + --inline-blank-nodes \ + --source __$@ \ + --source-format turtle \ + --target _$@ \ + --target-format turtle + rm __$@ + mv _$@ $@ + +query-email_addresses_in_common.html: \ + crossover_linked_validation.ttl \ + query-email_addresses_in_common.sparql + rm -f _$@ + source $(top_srcdir)/venv/bin/activate \ + && case_sparql_select \ + --no-index \ + --use-prefixes \ + _$@ \ + query-email_addresses_in_common.sparql \ + drafting.ttl \ + ../crossover_heist/crossover_heist.json \ + ../crossover_wmd/crossover_wmd.json \ + crossover_linked.json + mv _$@ $@ diff --git a/examples/crossover_linked/crossover_linked.json b/examples/crossover_linked/crossover_linked.json new file mode 100644 index 00000000..144120d1 --- /dev/null +++ b/examples/crossover_linked/crossover_linked.json @@ -0,0 +1,137 @@ +{ + "@context": { + "@vocab": "http://example.org/ontology/local#", + "case-investigation": "https://ontology.caseontology.org/case/investigation/", + "drafting": "http://example.org/ontology/drafting/", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "kb": "http://example.org/kb/", + "uco-action": "https://ontology.unifiedcyberontology.org/uco/action/", + "uco-configuration": "https://ontology.unifiedcyberontology.org/uco/configuration/", + "uco-core": "https://ontology.unifiedcyberontology.org/uco/core/", + "uco-identity": "https://ontology.unifiedcyberontology.org/uco/identity/", + "uco-location": "https://ontology.unifiedcyberontology.org/uco/location/", + "uco-observable": "https://ontology.unifiedcyberontology.org/uco/observable/", + "uco-role": "https://ontology.unifiedcyberontology.org/uco/role/", + "uco-tool": "https://ontology.unifiedcyberontology.org/uco/tool/", + "uco-types": "https://ontology.unifiedcyberontology.org/uco/types/", + "uco-vocabulary": "https://ontology.unifiedcyberontology.org/uco/vocabulary/", + "xsd": "http://www.w3.org/2001/XMLSchema#" + }, + "@graph": [ + { + "@id": "kb:Investigation-16a1c26a-60bf-4345-a863-53a138b73f0f", + "@type": "case-investigation:Investigation", + "uco-core:name": "CROSSOVER_2018_JOINT", + "uco-core:description": "Joint investigation", + "rdfs:comment": [ + "This investigation's set of uco-core:object values is seeded with the two investigations and the pair of email addresses with fully matching literal-values found in each investigation.", + "As an exercise of CASE Issue 138 and UCO Issue 544, the objects linked with uco-core:object are also linked with hasParticipant and hasPerdurantProperPart." + ], + "uco-core:object": [ + { + "@id": "kb:Investigation1-85c7b8d1-54e0-4023-847a-20e0f55dd48e" + }, + { + "@id": "kb:EmailAddress-5f63c12b-115a-474f-b1b2-15ebdb2fce31" + }, + { + "@id": "kb:EmailAddress-d2bc0936-e1c5-4b55-8a1b-af2b3a2b145c" + }, + { + "@id": "kb:investigation-99892fd4-ea24-46b5-be68-a69978d6ab98" + }, + { + "@id": "kb:emailaddress-456a2bac-8c21-11e9-8902-0c4de9c24de5" + }, + { + "@id": "kb:emailaddress-99d72bac-8c21-11e9-8902-0c4de9c21b53" + } + ], + "drafting:hasParticipant": [ + { + "@id": "kb:EmailAddress-5f63c12b-115a-474f-b1b2-15ebdb2fce31" + }, + { + "@id": "kb:EmailAddress-d2bc0936-e1c5-4b55-8a1b-af2b3a2b145c" + }, + { + "@id": "kb:emailaddress-456a2bac-8c21-11e9-8902-0c4de9c24de5" + }, + { + "@id": "kb:emailaddress-99d72bac-8c21-11e9-8902-0c4de9c21b53" + } + ], + "drafting:hasPerdurantProperPart": [ + { + "@id": "kb:Investigation1-85c7b8d1-54e0-4023-847a-20e0f55dd48e" + }, + { + "@id": "kb:investigation-99892fd4-ea24-46b5-be68-a69978d6ab98" + } + ] + }, + { + "@id": "kb:Relationship-e25bafbb-4621-4c83-aad9-89e69037e17d", + "@type": "drafting:PerdurantProperParthoodRelationship", + "uco-core:isDirectional": true, + "uco-core:kindOfRelationship": "Is_Part_of", + "uco-core:source": { + "@id": "kb:Investigation1-85c7b8d1-54e0-4023-847a-20e0f55dd48e" + }, + "uco-core:target": { + "@id": "kb:Investigation-16a1c26a-60bf-4345-a863-53a138b73f0f" + } + }, + { + "@id": "kb:Relationship-b8342e2b-8a91-423b-986e-ea9395334dd8", + "@type": "drafting:PerdurantProperParthoodRelationship", + "uco-core:isDirectional": true, + "uco-core:kindOfRelationship": "Is_Part_of", + "uco-core:source": { + "@id": "kb:investigation-99892fd4-ea24-46b5-be68-a69978d6ab98" + }, + "uco-core:target": { + "@id": "kb:Investigation-16a1c26a-60bf-4345-a863-53a138b73f0f" + } + }, + { + "@id": "kb:Investigation1-85c7b8d1-54e0-4023-847a-20e0f55dd48e", + "rdfs:comment": "TODO: This link should be incorporated into crossover_heist.json.", + "uco-core:object": { + "@id": "kb:InvestigativeAction-ba303f7f-02e8-45d7-bce2-40b846af14e0" + }, + "drafting:hasPerdurantProperPart": { + "@id": "kb:InvestigativeAction-ba303f7f-02e8-45d7-bce2-40b846af14e0" + } + }, + { + "@id": "kb:InvestigativeAction-ba303f7f-02e8-45d7-bce2-40b846af14e0", + "@type": "case-investigation:InvestigativeAction", + "uco-core:description": "Find email message", + "rdfs:comment": "This investigative action stub is incompletely written, but will need to be completed to tie the resulting email message to the chain of custody.", + "uco-action:result": { + "@id": "kb:EmailMessage-c5efd42c-d771-43aa-afe5-6b30740348e3" + } + }, + { + "@id": "kb:investigation-99892fd4-ea24-46b5-be68-a69978d6ab98", + "rdfs:comment": "TODO: This link should be incorporated into crossover_wmd.json.", + "uco-core:object": { + "@id": "kb:InvestigativeAction-df787264-ccb0-47fa-9fb3-4e50c0f3b1e2" + }, + "drafting:hasPerdurantProperPart": { + "@id": "kb:InvestigativeAction-df787264-ccb0-47fa-9fb3-4e50c0f3b1e2" + } + }, + { + "@id": "kb:InvestigativeAction-df787264-ccb0-47fa-9fb3-4e50c0f3b1e2", + "@type": "case-investigation:InvestigativeAction", + "uco-core:description": "Find email message", + "rdfs:comment": "This investigative action stub is incompletely written, but will need to be completed to tie the resulting email message to the chain of custody.", + "uco-action:result": { + "@id": "kb:emailmessage-2c032220-8c21-11e9-9c99-0c4de9c21b53" + } + } + ] +} diff --git a/examples/crossover_linked/drafting.ttl b/examples/crossover_linked/drafting.ttl new file mode 100644 index 00000000..e6514fd3 --- /dev/null +++ b/examples/crossover_linked/drafting.ttl @@ -0,0 +1,307 @@ +@prefix case-investigation: . +@prefix drafting: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix uco-action: . +@prefix uco-core: . +@prefix xsd: . + +drafting:Endurant + a + owl:Class , + sh:NodeShape + ; + rdfs:subClassOf uco-core:UcoObject ; + rdfs:isDefinedBy ; + owl:disjointWith drafting:Perdurant ; + sh:targetClass drafting:Endurant ; + . + +drafting:Endurant-disjointWith-Perdurant + a sh:NodeShape ; + rdfs:isDefinedBy ; + sh:not [ + a sh:NodeShape ; + sh:class drafting:Perdurant ; + ] ; + sh:targetClass drafting:Endurant ; + . + +drafting:ParthoodRelationship + a + owl:Class , + sh:NodeShape + ; + rdfs:comment + "A Parthood Relationship is a relationship where the source is a part of the target. (I.e., the 'component' thing is the source, the 'composite' thing is the target.)"@en , + "TODO - consider for proposal."@en + ; + rdfs:subClassOf + uco-core:Relationship , + [ + a owl:Restriction ; + owl:onProperty uco-core:isDirectional ; + owl:hasValue true ; + ] , + [ + a owl:Restriction ; + owl:onProperty uco-core:source ; + owl:allValuesFrom [ + a owl:Restriction ; + owl:onProperty drafting:isPartOf ; + owl:minCardinality "1"^^xsd:nonNegativeInteger ; + ] ; + ] , + [ + a owl:Restriction ; + owl:onProperty uco-core:target ; + owl:allValuesFrom [ + a owl:Restriction ; + owl:onProperty drafting:hasPart ; + owl:minCardinality "1"^^xsd:nonNegativeInteger ; + ] ; + ] + ; + sh:not [ + a sh:NodeShape ; + sh:property [ + a sh:PropertyShape ; + sh:hasValue false ; + sh:path uco-core:isDirectional ; + ] ; + ] ; + sh:targetClass drafting:ParthoodRelationship ; + . + +drafting:ParticipationRelationship + a + owl:Class , + sh:NodeShape + ; + rdfs:comment "The directionality of the ParticipationRelationship is that the source participates in the target."@en ; + rdfs:comment "TODO - consider for proposal."@en ; + rdfs:subClassOf + drafting:ParthoodRelationship , + [ + a owl:Restriction ; + owl:onProperty uco-core:source ; + owl:allValuesFrom drafting:Endurant ; + ] , + [ + a owl:Restriction ; + owl:onProperty uco-core:target ; + owl:allValuesFrom drafting:Perdurant ; + ] + ; + sh:property + [ + a sh:PropertyShape ; + sh:class drafting:Endurant ; + sh:path uco-core:source ; + ] , + [ + a sh:PropertyShape ; + sh:class drafting:Perdurant ; + sh:path uco-core:target ; + ] + ; + sh:targetClass drafting:ParticipationRelationship ; + . + +drafting:Perdurant + a + owl:Class , + sh:NodeShape + ; + rdfs:isDefinedBy ; + rdfs:subClassOf uco-core:UcoObject ; + owl:disjointWith drafting:Endurant ; + sh:targetClass drafting:Perdurant ; + . + +drafting:PerdurantProperParthoodRelationship + a + owl:Class , + sh:NodeShape + ; + rdfs:comment "The directionality of the PerdurantProperParthoodRelationship is that the source is a part of the target in the context of perdurant composition."@en ; + rdfs:comment "TODO - consider for proposal."@en ; + rdfs:subClassOf + drafting:ParthoodRelationship , + [ + a owl:Restriction ; + owl:onProperty uco-core:source ; + owl:allValuesFrom drafting:Perdurant ; + ] , + [ + a owl:Restriction ; + owl:onProperty uco-core:target ; + owl:allValuesFrom drafting:Perdurant ; + ] + ; + sh:property + [ + a sh:PropertyShape ; + sh:class drafting:Perdurant ; + sh:path uco-core:source ; + ] , + [ + a sh:PropertyShape ; + sh:class drafting:Perdurant ; + sh:path uco-core:target ; + ] + ; + sh:targetClass drafting:PerdurantProperParthoodRelationship ; + . + +drafting:hasPart + a owl:ObjectProperty ; + rdfs:comment + 'TODO - Because of the potential for the inferred parthood relationship to end, this may need to be spelled "hadPart" in the general case.'@en , + "TODO - consider for proposal."@en , + "The hasPart predicate implies the existence of a parthood relationship, where the RDF subject of hasPart is the uco-core:target of the parthood relationship."@en + ; + owl:inverseOf drafting:isPartOf ; + + owl:propertyChainAxiom ( + [ + owl:inverseOf uco-core:target ; + ] + uco-core:source + ) ; + rdfs:domain uco-core:UcoObject ; + rdfs:range uco-core:UcoObject ; + . + +drafting:hasParticipant + a owl:ObjectProperty ; + rdfs:subPropertyOf drafting:hasPart ; + rdfs:comment "The property chain axiom of hasPart is specialized by this property to imply a ParticipationRelationship."@en ; + rdfs:isDefinedBy ; + owl:inverseOf drafting:isParticipantIn ; + rdfs:domain drafting:Perdurant ; + rdfs:range drafting:Endurant ; + . + +drafting:hasParticipant-objects-shape + a sh:NodeShape ; + sh:class drafting:Endurant ; + sh:targetObjectsOf drafting:hasParticipant ; + . + +drafting:hasParticipant-subjects-shape + a sh:NodeShape ; + sh:class drafting:Perdurant ; + sh:targetSubjectsOf drafting:hasParticipant ; + . + +drafting:hasPerdurantProperPart + a owl:ObjectProperty ; + rdfs:subPropertyOf drafting:hasPart ; + rdfs:comment + "TODO - consider for proposal."@en , + "The property chain axiom of hasPart implies a PerdurantProperParthoodRelationship."@en + ; + owl:inverseOf drafting:isPerdurantProperPartOf ; + rdfs:domain drafting:Perdurant ; + rdfs:range drafting:Perdurant ; + . + +drafting:hasPerdurantProperPart-objects-shape + a sh:NodeShape ; + sh:class drafting:Perdurant ; + sh:targetObjectsOf drafting:hasPerdurantProperPart ; + . + +drafting:hasPerdurantProperPart-subjects-shape + a sh:NodeShape ; + sh:class drafting:Perdurant ; + sh:targetSubjectsOf drafting:hasPerdurantProperPart ; + . + +drafting:isPartOf + a owl:ObjectProperty ; + rdfs:comment + 'TODO - Because of the potential for the inferred parthood relationship to end, this may need to be spelled "wasPartOf" in the general case.'@en , + "TODO - consider for proposal."@en , + "The isPartOf predicate implies the existence of a parthood relationship, where the RDF subject of isPartOf is the uco-core:source of the parthood relationship."@en + ; + owl:propertyChainAxiom ( + [ + owl:inverseOf uco-core:source ; + ] + uco-core:target + ) ; + rdfs:domain uco-core:UcoObject ; + rdfs:range uco-core:UcoObject ; + . + +drafting:isParticipantIn + a owl:ObjectProperty ; + rdfs:subPropertyOf drafting:isPartOf ; + rdfs:comment + "TODO - consider for proposal."@en , + "The property chain axiom of isPartOf is specialized by this property to imply a ParticipationRelationship."@en + ; + owl:inverseOf drafting:hasParticipant ; + rdfs:domain drafting:Endurant ; + rdfs:range drafting:Perdurant ; + . + +drafting:isParticipantIn-objects-shape + a sh:NodeShape ; + sh:class drafting:Perdurant ; + sh:targetObjectsOf drafting:isParticipantIn ; + . + +drafting:isParticipantIn-subjects-shape + a sh:NodeShape ; + sh:class drafting:Endurant ; + sh:targetSubjectsOf drafting:isParticipantIn ; + . + +drafting:isPerdurantProperPartOf + a owl:ObjectProperty ; + rdfs:subPropertyOf drafting:isPartOf ; + rdfs:comment "The property chain axiom of isPartOf implies a PerdurantProperParthoodRelationship."@en ; + rdfs:isDefinedBy ; + owl:inverseOf drafting:hasPerdurantProperPart ; + rdfs:domain drafting:Perdurant ; + rdfs:range drafting:Perdurant ; + . + +drafting:isPerdurantProperPartOf-objects-shape + a sh:NodeShape ; + sh:class drafting:Perdurant ; + sh:targetObjectsOf drafting:isPerdurantProperPartOf ; + . + +drafting:isPerdurantProperPartOf-subjects-shape + a sh:NodeShape ; + sh:class drafting:Perdurant ; + sh:targetSubjectsOf drafting:isPerdurantProperPartOf ; + . + +case-investigation:Investigation + rdfs:subClassOf drafting:Perdurant ; + . + +uco-action:Action + rdfs:subClassOf drafting:Perdurant ; + . + +uco-core:Item + rdfs:subClassOf drafting:Endurant ; + . + +[] + a owl:Axiom ; + owl:annotatedSource case-investigation:Investigation ; + owl:annotatedProperty rdfs:subClassOf ; + owl:annotatedTarget drafting:Perdurant ; + rdfs:comment "NOTE - At the time of initial drafting of this file, this is known to conflict with the implementation state of CASE's Investigation object."@en ; + rdfs:isDefinedBy ; + . + diff --git a/examples/crossover_linked/query-email_addresses_in_common.sparql b/examples/crossover_linked/query-email_addresses_in_common.sparql new file mode 100644 index 00000000..77bfc469 --- /dev/null +++ b/examples/crossover_linked/query-email_addresses_in_common.sparql @@ -0,0 +1,20 @@ +SELECT ?lAddressValue ?lInvestigationName ?nInvestigation ?nEmailAddress +WHERE { + ?nInvestigation + a case-investigation:Investigation ; + uco-core:name ?lInvestigationName ; + uco-core:object ?nInvestigativeAction ; + . + ?nInvestigativeAction + a case-investigation:InvestigativeAction ; + uco-action:result ?nEmailMessage ; + . + ?nEmailAddress + a uco-observable:EmailAddress ; + uco-core:hasFacet / uco-observable:addressValue ?lAddressValue ; + . + ?nEmailMessage + uco-core:hasFacet / (uco-observable:from|uco-observable:to|uco-observable:cc|uco-observable:bcc) ?nEmailAddress ; + . +} +ORDER BY ?lAddressValue ?lInvestigationName ?nInvestigation ?nEmailAddress diff --git a/examples/crossover_wmd/src/crossover_wmd-email.json b/examples/crossover_wmd/src/crossover_wmd-email.json index 46fcc743..e8bf769f 100644 --- a/examples/crossover_wmd/src/crossover_wmd-email.json +++ b/examples/crossover_wmd/src/crossover_wmd-email.json @@ -20,7 +20,9 @@ "uco-observable:bodyRaw": { "@id": "kb:contentdata-f3b4a8da-d3ba-46b7-a7a0-3c17ec13648d" }, - "uco-observable:fromRef": null, + "uco-observable:from": { + "@id": "kb:emailaddress-456a2bac-8c21-11e9-8902-0c4de9c24de5" + }, "uco-observable:toRef": null, "uco-observable:ccRefs": null, "uco-observable:bccRefs": null, diff --git a/examples/crossover_wmd/src/crossover_wmd-supplemental.json b/examples/crossover_wmd/src/crossover_wmd-supplemental.json new file mode 100644 index 00000000..a8446200 --- /dev/null +++ b/examples/crossover_wmd/src/crossover_wmd-supplemental.json @@ -0,0 +1,10 @@ +[ + { + "@id": "kb:emailaccount-99d72bac-8c21-11e9-8902-0c4de9c21b53", + "rdfs:comment": "TODO - Discuss." + }, + { + "@id": "kb:email-message-facet-6c0d5813-5557-481d-95f3-b5f660e3e102", + "rdfs:comment": "TODO - Fill out, or delete, the incomplete 'ref' triples." + } +]