Temporal parts and Predicates

First issue: 2022-09-20 


The use of templates has as advantage that these can precisely define the semantics. BUT... they require an equally precise way of modeling, and that skill appears to be in short supply. Customary relational data models are easier, because adding a data element does not require much more than a textual definition (at best). Templates define the semantics of that data element in terms of the ISO 15926-2 upper ontology, so in all necessary detail.
The alternative approach, explained in this topic, allows for the re-use of those as-is data elements and placing them in the 4D framework of ISO 15926.


In an earlier version of ISO 15926-2 we had "Associations" that got a time stamp. In the IS (International Standard) version these have been replaced with "Relationships" without such a time stamp. Instead the time stamp was given to the temporal part(s) that are related by such a Relationship.
In Part 7 the templates do include the temporal parts, but these had to be made implicit, because there is no commercial software that can handle temporal parts. For that reason they could not be explicitly included in the template signature and we had to address the temporal whole and by convention the temporal part, valid at the valEffectiveDate of the template instance.

The basic model of the alternative approach is as follows:


To further show the alternative approach a small relational table, from the CFIHOS data model, will be mapped:

Most data elements are fairly easy to map to templates, but something like 'Tag property margin' takes some serious modeling, because it is a value that results from Process Engineering/Mechanical Engineering where for technical reasons a markup is defined.
Before representing this table in the alternative approach some remarks are required about the way these data are collected:
  • All information about X is to be attributed to the temporal part of X valid at the time the information became valid/relevant.
  • Most (not all) data are commonly shown on documents, including screen layouts that function as such. The example below assumes that a full dump of all data is made and represented.
  • Mapping data in dumps requires for each Tag (in this example) only one temporal part as the placeholder for the dumped data. In case data didn't change since last time it still may make sense to represent them anyway as a kind of reassurance that they were still valid. But of course these new, but redundant, data could also be filtered out.
Here is the representation after mapping from the P&ID, where it is assumed that there isn't a declaration for the Tag yet:

@prefix ex: <http://www.example.org/> . # the namespace for plant data of the Example org
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix dm: <http://data.15926.org/dm/> . # the ISO 15926-2 entity types
@prefix lci: <http://data.15926.org/lci/> . # additional entity types
@prefix pred: <http://data.15926.org/pred/> . # definition of generic predicates
@prefix tpl: <http://data.15926.org/tpl/> . # the ISO 15926-7 template specifications
@prefix rdl: <http://data.15926.org/rdl/> . # the ISO 15926-4 reference data
@prefix exrdl: <http://www.example.org/rdl/> . # the local RDL extension of Example org
@prefix meta: <http://data.15926.org/meta/> . # meta data

# Declaration of the "wholelife" Tag (the "anchor")

       rdf:type lci:InanimatePhysicalObject, dm:WholeLifeIndividual, lci:NonActualIndividual, rdl:RDS297539 ; # CONTROL VALVE
       rdfs:label "600-036FV001" ;
       meta:valEffectiveDate "2022-08-19T14:23:00Z"^^xsd:dateTime .

# Declaration of a temporal part, where the typing is being specialized
       pred:temporalPartOf ex:9d3bf126-afda-4246-8704-c8292fef963c ;
       rdf:type rdl:RDS5767330 ; # GLOBE CONTROL VALVE (since that symbol was shown on the P&ID at time of data extraction)
       rdfs:label "600-036FV001_2022-08-19T14:23:00Z" ; # tag number + effective date (or any other modifier)
       meta:valEffectiveDate "2022-08-19T14:23:00Z"^^xsd:dateTime .

Later a mapping is done from above relational data base table:

# Declaration of a temporal part and related predicates

       pred:temporalPartOf ex:9d3bf126-afda-4246-8704-c8292fef963c ;
       rdfs:label "600-036FV001_2022-09-15T14:30:00Z" ;
       meta:valEffectiveDate "2022-09-15T14:30:00Z"^^xsd:dateTime .

ex:ef6f6e73-e8ca-4451-afb7-5cda196069d1 exrdl:plantCode ex:2497f34d-05b8-43c7-9112-ddcb5261376c . # fetched via "600", see Note 1 below
ex:ef6f6e73-e8ca-4451-afb7-5cda196069d1 exrdl:propertyName rdl:RDS369629 . # fetched from RDL via 'normal operating pressure'
ex:ef6f6e73-e8ca-4451-afb7-5cda196069d1 exrdl:processActivityCode ex:84b20fa3-0a78-487a-808e-400858d21ee0 . # fetched via "PROC_07"
ex:ef6f6e73-e8ca-4451-afb7-5cda196069d1 exrdl:processStreamCode ex:b947a964-1816-4055-9350-82da37c502cc . # fetched via "MS-07"
ex:ef6f6e73-e8ca-4451-afb7-5cda196069d1 exrdl:tagPropertyMarginRatioInBarg "0.6"^^xsd:decimal . # see Note 2
ex:ef6f6e73-e8ca-4451-afb7-5cda196069d1 exrdl:normalOperatingPressureInBarg "10.3"^^xsd:decimal . # see Note 2

NOTE 1 - The UUID of the WholeLife range object is to be found via the given label (presumably that has already been declared); then create a temporal part with a valEffectiveDate of the given dateTime and use that UUID. The temporal parts at both sides of an ObjectProperty shall have the same valEffectiveDate.
NOTE 2 - The selection of the proper predicate depends on the given 'Unit of measure code'

The above table instance is represented in N-triples:

<http://www.example.org/ef6f6e73-e8ca-4451-afb7-5cda196069d1> <http://www.w3.org/2000/01/rdf-schema#label>                         "600-036FV001_2022-09-15T14:30:00Z" .
<http://www.example.org/ef6f6e73-e8ca-4451-afb7-5cda196069d1> <http://data.15926.org/pred/temporalPartOf>                              <http://www.example.org/9d3bf126-afda-4246-8704-c8292fef963c> .
<http://www.example.org/ef6f6e73-e8ca-4451-afb7-5cda196069d1> <http://www.example.org/rdl/plantCode>                                    <http://www.example.org/2497f34d-05b8-43c7-9112-ddcb5261376c> .
<http://www.example.org/ef6f6e73-e8ca-4451-afb7-5cda196069d1> <http://www.example.org/rdl/processActivityCode>                    <http://www.example.org/84b20fa3-0a78-487a-808e-400858d21ee0> .
<http://www.example.org/ef6f6e73-e8ca-4451-afb7-5cda196069d1> <http://www.example.org/rdl/processStreamCode>                    <http://www.example.org/b947a964-1816-4055-9350-82da37c502cc> .
<http://www.example.org/ef6f6e73-e8ca-4451-afb7-5cda196069d1> <http://www.example.org/rdl/propertyName>                              <http://data.15926.org/rdl/RDS369629> .
<http://www.example.org/ef6f6e73-e8ca-4451-afb7-5cda196069d1> <http://www.example.org/rdl/tagPropertyMarginRatioInBarg>    "0.6"^^<http://www.w3.org/2001/XMLSchema#decimal> .
<http://www.example.org/ef6f6e73-e8ca-4451-afb7-5cda196069d1> <http://www.example.org/rdl/normalOperatingPressureInBarg> "10.3"^^<http://www.w3.org/2001/XMLSchema#decimal> .
<http://www.example.org/ef6f6e73-e8ca-4451-afb7-5cda196069d1> <http://data.15926.org/meta/valEffectiveDate>                           "2022-09-15T14:30:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> .

# This requires some standardization work

# Once-only local declaration of Predicates, required to avoid misunderstandings
       rdf:type owl:ObjectProperty ;
       rdfs:subPropertyOf  pred:locatedIn ;
       rdfs:domain dm:PhysicalObject ;
       rdfs:range rdl:RDS7151797 ; # PLANT - specialization of the range object of pred:locatedIn

       rdf:type owl:ObjectProperty ;
       rdfs:subPropertyOf  pred:hasPropertyType ;
       rdfs:domain dm:PhysicalObject ;
       rdfs:range dm:SinglePropertyDimension .

       rdf:type owl:ObjectProperty ;
       rdfs:subPropertyOf  pred:participatesIn ;
       rdfs:domain dm:PhysicalObject ;
       rdfs:range  dm:Activity .

       rdf:type owl:ObjectProperty ;
       rdfs:subPropertyOf pred:contains ;
       rdfs:domain dm:PhysicalObject ;
       rdfs:range dm:Stream .

       rdf:type owl:DatatypeProperty ;
       rdfs:subPropertyOf pred:pressureInBarg  ;
       rdfs:domain dm:SinglePropertyDimension ;
       rdfs:range xsd:decimal .

       rdf:type owl:DatatypeProperty ;
       rdfs:subPropertyOf pred:pressureInBarg  ;
       rdfs:domain dm:SinglePropertyDimension ;
       rdfs:range xsd:decimal .
# where reference is made to the following standardized generic Predicates:
       rdf:type owl:ObjectProperty ;
       skos:definition "A 'locatedIn' predicate refers to the range object in which the domain subject is located"@en ;
       rdfs:domain dm:PhysicalObject ;
       rdfs:range dm:PhysicalObject .

       rdf:type owl:ObjectProperty ;
       skos:definition "A 'hasPropertyType' predicate refers to an instance of http://data.15926.org/dm/SinglePropertyDimension that, in some magnitude, defines the state of the domain PhysicalObject or of the members of the domain Class"@en ;
       rdfs:domain dm:Thing ; ;
       rdfs:range dm:SinglePropertyDimension .

       rdf:type owl:ObjectProperty ;
       skos:definition "A 'participatesIn' predicate refers to an Activity in which the domain participates"@en .
       rdfs:domain dm:PhysicalObject ;
       rdfs:range dm:Activity .

       rdf:type owl:ObjectProperty ;
       skos:definition "A 'contains' predicate refers to a PhysicalObject, mostly a Stream, that is contained in the domain PhysicalObject"@en ;
       rdfs:domain dm:PhysicalObject ;
       rdfs:domain dm:PhysicalObject .

       rdf:type owl:DatatypeProperty ;
       skos:definition "A 'pressureInBarg' predicate refers to a numerical value of a Pressure that is mapped to the BAR GAUGE Scale, as defined by http://data.15926.org/rdl/RDS1348874"@en ;
       rdfs:domain dm:Thing ;
       rdfs:range xsd:decimal .

Optional precise definition of semantics

Optionally each Predicate can be precisely defined with a specialized instance of a Part 7 Template, so in fact a mapping to templates in disguise, be it that in this case each mapping has to be done only once and by a standardization body (please don't hold your breath for this).
This can be done by using the rdfs:isDefinedBy predicate.
One random example:

Validating with SHACL

The instances of declarations and predicates can be validated with SHACL "shapes", as described in the topic 'Validating RDF data with SHACL' (which, btw, needs an update).
It is conceivable that the SHACL code can be derived from the predicate definitions. That still has to be determined (contributions are welcome!)


The advantages of the above method vs the customary method with templates are:
  1. Users can design their own predicates, as a specialization of standardized generic predicates, that can be defined with specialized templates, thus becoming 15926-compliant
  2. Modeling can be done by engineers (with some training)
  3. Less 'outlandish' for RDF experts
  4. Easier to query
  5. Less verbose
  6. Easier to develop software because highly generic and repetitive.