diff --git a/.gitmodules b/.gitmodules index 6922aea9..e1b8fe48 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,3 +14,15 @@ path = dependencies/CASE-unstable-2.0.0 url = https://github.com/casework/CASE-Archive.git branch = unstable-2.0.0 +[submodule "dependencies/CDO-Shapes-BFO"] + path = dependencies/CDO-Shapes-BFO + url = https://github.com/Cyber-Domain-Ontology/CDO-Shapes-BFO.git + branch = main +[submodule "dependencies/CDO-Shapes-Time"] + path = dependencies/CDO-Shapes-Time + url = https://github.com/Cyber-Domain-Ontology/CDO-Shapes-Time.git + branch = main +[submodule "dependencies/CDO-Shapes-gufo"] + path = dependencies/CDO-Shapes-gufo + url = https://github.com/Cyber-Domain-Ontology/CDO-Shapes-gufo.git + branch = main diff --git a/Makefile b/Makefile index 23738d53..e8d9d616 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,21 @@ all: \ $(MAKE) \ --directory dependencies/CASE-unstable-2.0.0 \ .git_submodule_init.done.log + # CDO-Shapes-BFO + test -r dependencies/CDO-Shapes-BFO/README.md \ + || git submodule update --init dependencies/CDO-Shapes-BFO + test -r dependencies/CDO-Shapes-BFO/README.md \ + || (echo "ERROR:Makefile:CDO-Shapes-BFO submodule README.md file not found, even though CDO-Shapes-BFO submodule initialized." >&2 ; exit 2) + # CDO-Shapes-Time + test -r dependencies/CDO-Shapes-Time/README.md \ + || git submodule update --init dependencies/CDO-Shapes-Time + test -r dependencies/CDO-Shapes-Time/README.md \ + || (echo "ERROR:Makefile:CDO-Shapes-Time submodule README.md file not found, even though CDO-Shapes-Time submodule initialized." >&2 ; exit 2) + # CDO-Shapes-gufo + test -r dependencies/CDO-Shapes-gufo/README.md \ + || git submodule update --init dependencies/CDO-Shapes-gufo + test -r dependencies/CDO-Shapes-gufo/README.md \ + || (echo "ERROR:Makefile:CDO-Shapes-gufo submodule README.md file not found, even though CDO-Shapes-gufo submodule initialized." >&2 ; exit 2) # Retrieve rdf-toolkit.jar. $(MAKE) \ --directory dependencies/CASE-develop \ diff --git a/dependencies/CDO-Shapes-BFO b/dependencies/CDO-Shapes-BFO new file mode 160000 index 00000000..1ce73867 --- /dev/null +++ b/dependencies/CDO-Shapes-BFO @@ -0,0 +1 @@ +Subproject commit 1ce73867dfcc132a1465a578d2a5d591c76f8462 diff --git a/dependencies/CDO-Shapes-Time b/dependencies/CDO-Shapes-Time new file mode 160000 index 00000000..e845f23d --- /dev/null +++ b/dependencies/CDO-Shapes-Time @@ -0,0 +1 @@ +Subproject commit e845f23d370d8125ed0efe1cf34c5a546c3df083 diff --git a/dependencies/CDO-Shapes-gufo b/dependencies/CDO-Shapes-gufo new file mode 160000 index 00000000..aebe0182 --- /dev/null +++ b/dependencies/CDO-Shapes-gufo @@ -0,0 +1 @@ +Subproject commit aebe0182fc7b75b5ef148f5b12cfe82192cd4336 diff --git a/examples/illustrations/existence_intervals/README.md b/examples/illustrations/existence_intervals/README.md index a998f002..0b6926f2 100644 --- a/examples/illustrations/existence_intervals/README.md +++ b/examples/illustrations/existence_intervals/README.md @@ -216,4 +216,56 @@ _Aside_: A side-by-side view of the gUFO and OWL-Time coverage show that an onto | --- | --- | | ![Abstraction - OWL-Time Temporal Entity](figures/abstraction_time.svg) | ![Abstraction - gUFO Concrete Individual](figures/abstraction_gufo.svg) | + +## BFO + +(BFO version: [2020](https://github.com/BFO-ontology/BFO-2020).) + +BFO's topmost class that describes an object that exists in a period of time is "Entity" (`obo:BFO_0000001`). The direct subclasses "Continuant" and "Occurrent", which correspond with "Endurant" and "Perdurant" respectively, do not specialize the restrictions on the existence property "exists at". + +For reference, these are the class and property labels used in the illustration: + +| Structural type | IRI | Label | Notes | +| --- | --- | --- | --- | +| `owl:Class` | `obo:BFO_0000001` | (BFO 1) entity | | +| `owl:Class` | `obo:BFO_0000002` | (BFO 2) continuant | | +| `owl:Class` | `obo:BFO_0000003` | (BFO 3) occurrent | | +| `owl:Class` | `obo:BFO_0000008` | (BFO 8) temporal region | | +| `owl:Class` | `obo:BFO_0000038` | (BFO 38) one-dimensional temporal region | Not necessarily continuous (can have gaps). | +| `owl:Class` | `obo:BFO_0000148` | (BFO 148) zero-dimensional temporal region | "...a temporal region that is a whole consisting of one or more separated temporal instants as parts." | +| `owl:Class` | `obo:BFO_0000202` | (BFO 202) temporal interval | Subclass of BFO 38; continous (no gaps or breaks). | +| `owl:Class` | `obo:BFO_0000203` | (BFO 203) temporal instant | Subclass of BFO 148; has no proper temporal parts. | +| `owl:ObjectProperty` | `obo:BFO_0000108` | exists at | Range is BFO 8. | +| `owl:ObjectProperty` | `obo:BFO_0000222` | has first instant | Range is constrained to BFO 203, not 148 (instant, not 0-d region). | +| `owl:ObjectProperty` | `obo:BFO_0000224` | has last instant | (As with BFO 222.) | + +_Restrictions_: + +* Usage of the BFO properties 222 and 224 (first and last instant) restrict the alignment of `ex:Instant` to `obo:BFO_0000203` (temporal instant), which is more restrictive than `obo:BFO_0000148` (zero-dimensional temporal region). +* If existence intervals are required by a BFO-adopting ontology ontology to be continuous, the adopting ontology must use `obo:BFO_0000202` (temporal interval) rather than `obo:BFO_0000038` (one-dimensional temporal region). + +The referenced version of BFO does not define any `owl:DatatypeProperty`s. + +![Abstraction - BFO Entity](figures/abstraction_bfo.svg) + +The mapping for BFO's `entity` (BFO-1) would be as follows: + +| Example class or triple | Corresponding class or triple | +| --- | --- | +| `ex:TimeBoundedThing` | `obo:BFO_0000001` | +| `ex:ExistenceInterval` | `obo:BFO_0000038` | +| `ex:Instant` | `obo:BFO_0000203` | +| `kb:T ex:hasExistenceInterval kb:E` | `kb:T obo:BFO_0000108 kb:E` | +| `kb:T ex:existsAtAndSince kb:T0` | N/A | +| `kb:T ex:existsUntil kb:T1` | N/A | +| `kb:T ex:hasCreationTimestamp "2020-..."^^xsd:dateTime` | N/A | +| `kb:T ex:hasTerminationTimestamp "2021-..."^^xsd:dateTime` | N/A | +| `kb:E ex:hasStart kb:T0` | `kb:E obo:BFO_0000222 kb:T0` | +| `kb:E ex:hasEnd kb:T1` | `kb:E obo:BFO_0000224 kb:T1` | +| `kb:E ex:hasBeginningTimestamp "2020-..."^^xsd:dateTime` | N/A | +| `kb:E ex:hasEndingTimestamp "2021-..."^^xsd:dateTime` | N/A | +| `kb:T0 ex:hasTimestamp "2020-..."^^xsd:dateTime` | N/A | +| `kb:T1 ex:hasTimestamp "2021-..."^^xsd:dateTime` | N/A | + + [^1]: gUFO represents instantations that are not always true with `gufo:TemporaryInstantiationSituation`. In the case where a person is temporarily a student, "student" is taken to be some subclass of "person" - e.g., `ex:Student rdfs:subClassOf ex:Person`. For some time, it holds that `kb:person-3393... a ex:Student`, but this is not always true. To hold this situationally-true statement in a knowledge graph, a `gufo:TemporaryInstantiationSituation` is included to note the conditions when `kb:person-3393...` is a `ex:Student`, instead of encoding the unqualified triple `kb:person-3393... a ex:Student`. See `kb:TemporaryInstantiationSituation-da1aa582-1358-49bb-b058-4c33990fb9e8` in [`existence_intervals.json`](existence_intervals.json) for a demonstration of this representation. diff --git a/examples/illustrations/existence_intervals/existence_intervals.json b/examples/illustrations/existence_intervals/existence_intervals.json index 05f0f832..8aec0209 100644 --- a/examples/illustrations/existence_intervals/existence_intervals.json +++ b/examples/illustrations/existence_intervals/existence_intervals.json @@ -96,6 +96,14 @@ "@id": "ex:Person" } }, + { + "@id": "kb:Entity-52d479e6-4b3e-4a21-a60a-29b08397a315", + "@type": "obo:BFO_0000001", + "obo:BFO_0000108": { + "@id": "kb:OneDimensionalTemporalRegion-95fc3589-849b-406b-85c4-3b2119121f1e" + }, + "rdfs:label": "T" + }, { "@id": "kb:ExistenceInterval-27802c47-1c75-43fa-ab4b-fc01aa6c2c92", "@type": "time:Interval", @@ -142,6 +150,17 @@ "rdfs:comment": "A thing with a time-bounded existence.", "rdfs:label": "T" }, + { + "@id": "kb:OneDimensionalTemporalRegion-95fc3589-849b-406b-85c4-3b2119121f1e", + "@type": "obo:BFO_0000038", + "obo:BFO_0000222": { + "@id": "kb:TemporalInstant-19f182b4-6bc8-4ad8-a456-56fa15aec976" + }, + "obo:BFO_0000224": { + "@id": "kb:TemporalInstant-3299e3a8-8d3e-43c7-a142-14bb41638669" + }, + "rdfs:label": "E" + }, { "@id": "kb:Person-3393dfc0-c765-4710-86db-8182c34de806", "@type": "ex:Person", @@ -150,6 +169,16 @@ }, "rdfs:label": "J. Doe" }, + { + "@id": "kb:TemporalInstant-19f182b4-6bc8-4ad8-a456-56fa15aec976", + "@type": "obo:BFO_0000203", + "rdfs:label": "T0" + }, + { + "@id": "kb:TemporalInstant-3299e3a8-8d3e-43c7-a142-14bb41638669", + "@type": "obo:BFO_0000203", + "rdfs:label": "T1" + }, { "@id": "kb:TemporaryInstantiationSituation-da1aa582-1358-49bb-b058-4c33990fb9e8", "@type": "gufo:TemporaryInstantiationSituation", diff --git a/examples/illustrations/existence_intervals/postvisit.mk b/examples/illustrations/existence_intervals/postvisit.mk new file mode 100644 index 00000000..0145b87e --- /dev/null +++ b/examples/illustrations/existence_intervals/postvisit.mk @@ -0,0 +1,55 @@ +#!/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. + +SHELL := /bin/bash + +top_srcdir := $(shell cd ../../.. ; pwd) + +bfo_ttl := $(top_srcdir)/dependencies/CDO-Shapes-BFO/dependencies/BFO.ttl +sh_bfo_ttl := $(top_srcdir)/dependencies/CDO-Shapes-BFO/shapes/sh-bfo.ttl + +gufo_ttl := $(top_srcdir)/dependencies/CDO-Shapes-gufo/dependencies/gufo.ttl +sh_gufo_ttl := $(top_srcdir)/dependencies/CDO-Shapes-gufo/shapes/sh-gufo.ttl + +time_ttl := $(top_srcdir)/dependencies/CDO-Shapes-Time/dependencies/time.ttl +sh_time_ttl := $(top_srcdir)/dependencies/CDO-Shapes-Time/shapes/sh-time.ttl + +all: + +.cdo-shapes.done.log: \ + $(bfo_ttl) \ + $(gufo_ttl) \ + $(sh_bfo_ttl) \ + $(sh_gufo_ttl) \ + $(sh_time_ttl) \ + $(time_ttl) \ + $(top_srcdir)/.venv.done.log \ + existence_intervals.json + source $(top_srcdir)/venv/bin/activate \ + && case_validate \ + --ontology-graph $(bfo_ttl) \ + --ontology-graph $(gufo_ttl) \ + --ontology-graph $(sh_bfo_ttl) \ + --ontology-graph $(sh_gufo_ttl) \ + --ontology-graph $(sh_time_ttl) \ + --ontology-graph $(time_ttl) \ + existence_intervals.json + touch $@ + +check: \ + .cdo-shapes.done.log + +clean: diff --git a/examples/illustrations/existence_intervals/src/README.md.in b/examples/illustrations/existence_intervals/src/README.md.in index 09787988..5d8bd0c1 100644 --- a/examples/illustrations/existence_intervals/src/README.md.in +++ b/examples/illustrations/existence_intervals/src/README.md.in @@ -177,4 +177,56 @@ _Aside_: A side-by-side view of the gUFO and OWL-Time coverage show that an onto | --- | --- | | ![Abstraction - OWL-Time Temporal Entity](figures/abstraction_time.svg) | ![Abstraction - gUFO Concrete Individual](figures/abstraction_gufo.svg) | + +## BFO + +(BFO version: [2020](https://github.com/BFO-ontology/BFO-2020).) + +BFO's topmost class that describes an object that exists in a period of time is "Entity" (`obo:BFO_0000001`). The direct subclasses "Continuant" and "Occurrent", which correspond with "Endurant" and "Perdurant" respectively, do not specialize the restrictions on the existence property "exists at". + +For reference, these are the class and property labels used in the illustration: + +| Structural type | IRI | Label | Notes | +| --- | --- | --- | --- | +| `owl:Class` | `obo:BFO_0000001` | (BFO 1) entity | | +| `owl:Class` | `obo:BFO_0000002` | (BFO 2) continuant | | +| `owl:Class` | `obo:BFO_0000003` | (BFO 3) occurrent | | +| `owl:Class` | `obo:BFO_0000008` | (BFO 8) temporal region | | +| `owl:Class` | `obo:BFO_0000038` | (BFO 38) one-dimensional temporal region | Not necessarily continuous (can have gaps). | +| `owl:Class` | `obo:BFO_0000148` | (BFO 148) zero-dimensional temporal region | "...a temporal region that is a whole consisting of one or more separated temporal instants as parts." | +| `owl:Class` | `obo:BFO_0000202` | (BFO 202) temporal interval | Subclass of BFO 38; continous (no gaps or breaks). | +| `owl:Class` | `obo:BFO_0000203` | (BFO 203) temporal instant | Subclass of BFO 148; has no proper temporal parts. | +| `owl:ObjectProperty` | `obo:BFO_0000108` | exists at | Range is BFO 8. | +| `owl:ObjectProperty` | `obo:BFO_0000222` | has first instant | Range is constrained to BFO 203, not 148 (instant, not 0-d region). | +| `owl:ObjectProperty` | `obo:BFO_0000224` | has last instant | (As with BFO 222.) | + +_Restrictions_: + +* Usage of the BFO properties 222 and 224 (first and last instant) restrict the alignment of `ex:Instant` to `obo:BFO_0000203` (temporal instant), which is more restrictive than `obo:BFO_0000148` (zero-dimensional temporal region). +* If existence intervals are required by a BFO-adopting ontology ontology to be continuous, the adopting ontology must use `obo:BFO_0000202` (temporal interval) rather than `obo:BFO_0000038` (one-dimensional temporal region). + +The referenced version of BFO does not define any `owl:DatatypeProperty`s. + +![Abstraction - BFO Entity](figures/abstraction_bfo.svg) + +The mapping for BFO's `entity` (BFO-1) would be as follows: + +| Example class or triple | Corresponding class or triple | +| --- | --- | +| `ex:TimeBoundedThing` | `obo:BFO_0000001` | +| `ex:ExistenceInterval` | `obo:BFO_0000038` | +| `ex:Instant` | `obo:BFO_0000203` | +| `kb:T ex:hasExistenceInterval kb:E` | `kb:T obo:BFO_0000108 kb:E` | +| `kb:T ex:existsAtAndSince kb:T0` | N/A | +| `kb:T ex:existsUntil kb:T1` | N/A | +| `kb:T ex:hasCreationTimestamp "2020-..."^^xsd:dateTime` | N/A | +| `kb:T ex:hasTerminationTimestamp "2021-..."^^xsd:dateTime` | N/A | +| `kb:E ex:hasStart kb:T0` | `kb:E obo:BFO_0000222 kb:T0` | +| `kb:E ex:hasEnd kb:T1` | `kb:E obo:BFO_0000224 kb:T1` | +| `kb:E ex:hasBeginningTimestamp "2020-..."^^xsd:dateTime` | N/A | +| `kb:E ex:hasEndingTimestamp "2021-..."^^xsd:dateTime` | N/A | +| `kb:T0 ex:hasTimestamp "2020-..."^^xsd:dateTime` | N/A | +| `kb:T1 ex:hasTimestamp "2021-..."^^xsd:dateTime` | N/A | + + [^1]: gUFO represents instantations that are not always true with `gufo:TemporaryInstantiationSituation`. In the case where a person is temporarily a student, "student" is taken to be some subclass of "person" - e.g., `ex:Student rdfs:subClassOf ex:Person`. For some time, it holds that `kb:person-3393... a ex:Student`, but this is not always true. To hold this situationally-true statement in a knowledge graph, a `gufo:TemporaryInstantiationSituation` is included to note the conditions when `kb:person-3393...` is a `ex:Student`, instead of encoding the unqualified triple `kb:person-3393... a ex:Student`. See `kb:TemporaryInstantiationSituation-da1aa582-1358-49bb-b058-4c33990fb9e8` in [`existence_intervals.json`](existence_intervals.json) for a demonstration of this representation. diff --git a/examples/illustrations/existence_intervals/src/existence_intervals-bfo-entity.json b/examples/illustrations/existence_intervals/src/existence_intervals-bfo-entity.json new file mode 100644 index 00000000..d4dc6f11 --- /dev/null +++ b/examples/illustrations/existence_intervals/src/existence_intervals-bfo-entity.json @@ -0,0 +1,31 @@ +[ + { + "@id": "kb:Entity-52d479e6-4b3e-4a21-a60a-29b08397a315", + "@type": "obo:BFO_0000001", + "rdfs:label": "T", + "obo:BFO_0000108": { + "@id": "kb:OneDimensionalTemporalRegion-95fc3589-849b-406b-85c4-3b2119121f1e" + } + }, + { + "@id": "kb:OneDimensionalTemporalRegion-95fc3589-849b-406b-85c4-3b2119121f1e", + "@type": "obo:BFO_0000038", + "rdfs:label": "E", + "obo:BFO_0000222": { + "@id": "kb:TemporalInstant-19f182b4-6bc8-4ad8-a456-56fa15aec976" + }, + "obo:BFO_0000224": { + "@id": "kb:TemporalInstant-3299e3a8-8d3e-43c7-a142-14bb41638669" + } + }, + { + "@id": "kb:TemporalInstant-19f182b4-6bc8-4ad8-a456-56fa15aec976", + "@type": "obo:BFO_0000203", + "rdfs:label": "T0" + }, + { + "@id": "kb:TemporalInstant-3299e3a8-8d3e-43c7-a142-14bb41638669", + "@type": "obo:BFO_0000203", + "rdfs:label": "T1" + } +] diff --git a/examples/illustrations/src/illustration-nosrc.mk b/examples/illustrations/src/illustration-nosrc.mk index bc4d63ff..52f52ed5 100644 --- a/examples/illustrations/src/illustration-nosrc.mk +++ b/examples/illustrations/src/illustration-nosrc.mk @@ -85,6 +85,9 @@ all: \ test ! -r figures/Makefile \ || $(MAKE) \ --directory figures + test ! -r postvisit.mk \ + || $(MAKE) \ + --file postvisit.mk .PHONY: \ check-pytest @@ -335,6 +338,10 @@ check: \ $(example_name)_validation-develop-2.0.0.ttl \ $(example_name)_validation-unstable.ttl \ $(example_name)_validation-unstable-2.0.0.ttl + test ! -r postvisit.mk \ + || $(MAKE) \ + --file postvisit.mk \ + check # Run pytest tests only if any are written. # (Pytest exits in an error state if called with no tests found.) @@ -348,6 +355,10 @@ check-pytest: \ ) clean: + @test ! -r postvisit.mk \ + || $(MAKE) \ + --file postvisit.mk \ + clean @rm -f \ .drafting.ttl.*.log \ figures/*.dot \