A patient health record -- tracking change with gufo:Situation and its five subclasses
Plain OWL assertions are timeless: :Nora a :OverweightPerson says Nora is (tenselessly) overweight,
with no way to say when. Most of the facts a health record needs to track -- a patient's weight, a
transient diagnosis, which heart is currently theirs -- are exactly the kind that hold for a while and then
stop holding. gUFO's gufo:Situation and its five subclasses reify "this held, during this
period" as an individual in its own right, giving you somewhere to attach a begin and end point. This
example walks through all five, on one patient's record.
Nora Whitfield's health record: her weight over two years, a period in which she counted as overweight, a heart transplant, a dental crown re-made in a different material, and a comparison with another patient at intake. (Patient names are fictional.)
Every pattern below follows the same "qualified relation" shape: the endurant stands in a situation via a
standsInQualified... property; the situation itself is further described with
concerns... properties (identifying what the situation is about) and, like any concrete
individual, with gufo:hasBeginPointInXSDDate/gufo:hasEndPointInXSDDate.
Rather than a single gufo:hasQualityValue assertion (as in
example 3, for a quality that does not change), each value Nora's
weight has taken becomes its own situation:
:NoraWeighs82KgIn2023 a gufo:QualityValueAttributionSituation ;
gufo:concernsQualityType :Weight ;
gufo:concernsQualityValue "82.0"^^xsd:double ;
gufo:hasBeginPointInXSDDate "2023-01-10"^^xsd:date ;
gufo:hasEndPointInXSDDate "2023-06-30"^^xsd:date .
:NoraWeighs75KgIn2024 a gufo:QualityValueAttributionSituation ;
gufo:concernsQualityType :Weight ;
gufo:concernsQualityValue "75.0"^^xsd:double ;
gufo:hasBeginPointInXSDDate "2024-01-15"^^xsd:date .
:Nora gufo:standsInQualifiedAttribution :NoraWeighs82KgIn2023 , :NoraWeighs75KgIn2024 .
:Weight here is just a plain subclass of gufo:Quality, used as the object of
gufo:concernsQualityType -- note this is a different use of "Weight" than instantiating it with
a reified quality individual (as Gemstone1Mass was in example 3): here the class itself is what is pointed
to, since gufo:concernsQualityType's range is gufo:EndurantType, not
gufo:Quality. This is OWL 2 punning again -- the same mechanism used throughout
example 1 and example 7, except here it happens implicitly: simply using :Weight as the object of a
property whose range is gufo:EndurantType is enough for a reasoner to type it accordingly,
without an explicit :Weight a gufo:Kind triple.
Instead of a plain, tenseless :Nora a :OverweightPerson, the period during which the phase applied
is recorded explicitly:
:NoraWasOverweightUntilJune2023 a gufo:TemporaryInstantiationSituation ;
gufo:concernsNonRigidType :OverweightPerson ;
gufo:hasBeginPointInXSDDate "2020-03-01"^^xsd:date ;
gufo:hasEndPointInXSDDate "2023-06-30"^^xsd:date .
:Nora gufo:standsInQualifiedInstantiation :NoraWasOverweightUntilJune2023 .
Note the end date lines up with when her weight (tracked above) drops below the overweight threshold -- the two situations are about the same change in the world, recorded from two different angles (a quality's value, and a phase's applicability).
A part that can be swapped out -- like a heart, once transplant surgery exists -- should not be linked to
its whole with a plain gufo:isComponentOf assertion (which example 2 used for a car's engine,
treating the link as essentially permanent). Instead, each parthood episode is its own situation:
:NoraHadNativeHeart a gufo:TemporaryParthoodSituation ;
gufo:concernsTemporaryWhole :Nora ;
gufo:hasEndPointInXSDDate "2024-03-05"^^xsd:date .
:NoraNativeHeart gufo:standsInQualifiedParthood :NoraHadNativeHeart .
:NoraHasDonorHeart a gufo:TemporaryParthoodSituation ;
gufo:concernsTemporaryWhole :Nora ;
gufo:hasBeginPointInXSDDate "2024-03-05"^^xsd:date .
:DonorHeart881 gufo:standsInQualifiedParthood :NoraHasDonorHeart .
What caused the second situation to start? The surgery itself, and gUFO has a property just for "an event brought this situation about":
:NoraHeartTransplant20240305 a :HeartTransplantSurgery ;
gufo:hasBeginPointInXSDDate "2024-03-05"^^xsd:date ;
gufo:broughtAbout :NoraHasDonorHeart .
Nora's dental crown keeps its identity across a repair, even though what it is made of changes -- exactly
the kind of case gufo:TemporaryConstitutionSituation is for (mirroring the Venus de Milo example
in the gUFO usage guide, which loses its arms without losing its identity):
:NoraCrownWasPorcelain a gufo:TemporaryConstitutionSituation ;
gufo:concernsConstitutedEndurant :NoraCrown ;
gufo:hasEndPointInXSDDate "2022-11-20"^^xsd:date .
:OriginalPorcelainBatch gufo:standsInQualifiedConstitution :NoraCrownWasPorcelain .
:NoraCrownIsResin a gufo:TemporaryConstitutionSituation ;
gufo:concernsConstitutedEndurant :NoraCrown ;
gufo:hasBeginPointInXSDDate "2022-11-21"^^xsd:date .
:ReplacementResinBatch gufo:standsInQualifiedConstitution :NoraCrownIsResin .
Finally, a relationship between two patients that depends on a quality that changes -- "heavier than" --
is qualified the same way, with the relationship type itself declared a
gufo:ComparativeRelationshipType derived from the Weight quality, exactly as the usage guide
recommends:
:heavierThan a owl:ObjectProperty , gufo:ComparativeRelationshipType ;
rdfs:domain :Patient ; rdfs:range :Patient ;
gufo:isDerivedFrom :Weight .
:NoraHeavierThanMiguelOn20240115 a gufo:TemporaryRelationshipSituation ;
gufo:concernsRelationshipType :heavierThan ;
:concernsLighterPatient :Miguel ;
gufo:hasBeginPointInXSDDate "2024-01-15"^^xsd:date ;
gufo:hasEndPointInXSDDate "2024-01-15"^^xsd:date .
:Nora :standsAsHeavierPatient :NoraHeavierThanMiguelOn20240115 .
gufo:contributedToTriggergufo:broughtAbout (step 3) links an event to a situation it is sufficient to explain.
Sometimes a situation only plays a part in causing an event, without being sufficient on its own -- gUFO's
gufo:contributedToTrigger is for that weaker claim, going the other direction (situation
→ event):
:NoraWasFebrileOnAdmission a gufo:TemporaryInstantiationSituation ;
gufo:concernsNonRigidType :FebrilePatient ;
gufo:hasBeginPointInXSDDateTimeStamp "2024-02-02T08:00:00Z"^^xsd:dateTimeStamp ;
gufo:hasEndPointInXSDDateTimeStamp "2024-02-02T14:00:00Z"^^xsd:dateTimeStamp ;
gufo:contributedToTrigger :SepsisAlert20240202 .
Nora's fever, by itself, does not guarantee the alert fires (other vitals matter too) -- it merely
contributed. This mirrors example 5's
gufo:historicallyDependsOn, but at the situation, rather than event-to-event, level.
This example only says that each pair of situations replaced one another -- it never models the
event in between that changed things (the transplant surgery is the one exception, via
gufo:broughtAbout). The gufoevents extension
supplies dedicated event classes for exactly these transitions, each already axiomatized to bring about the
right kind of situation: gufoevents:QualityValueChange for step 1's change in
Nora's weight, gufoevents:Declassification/Reclassification for step 2's phase
change, gufoevents:PartReplacement for step 3's heart transplant (a single complex event
composed of the separation of the native heart and the incorporation of the donor heart), and
gufoevents:ConstituentSubstitution for step 4's crown re-made in a different material. Reaching
for gufoevents is worthwhile whenever an ontology needs to reason about the change itself -- not just about
the before-and-after situations it connects.
See ontology.ttl for the complete file.
Each situation subclass carries its own qualified cardinality restrictions (e.g.
TemporaryConstitutionSituation requires exactly one gufo:concernsConstitutedEndurant
value that is a gufo:Object, and exactly one endurant standing in it via the inverse of
gufo:standsInQualifiedConstitution) -- these are exactly the kind of thing a DL reasoner checks
well.
gufo.ttl + ontology.ttl is
consistent, and every situation individual satisfies its class's restrictions (including the pairwise
disjointness between the five situation subclasses).cd examples/tests
.venv/bin/pytest -v -k 06-situations