Semantic Translation

The process of semantic translation is performed by IPSM based on the configuration of translation channel (using Apache Kafka publish-subscribe mode) or sequence of alignments received in REST request (using REST API). The steps element in an alignment will defines in what order cells are applied. Each cell is applied to the RDF graph being an output of previous cell. The application of a cell means that SPARQL UPDATE is generated from graph patterns in entity1 and entity2.

Lets know analyze step by step an example of transformation of one predefined RDF graph into another.

Let input RDF be:

{
 "@id": "p1ont:PositionMeasurementValue",
 "@type": "geo:Point",
 "geo:lat": {
   "@type" : "http://www.w3.org/2001/XMLSchema#float",
   "@value" : "52.3"
 },
 "geo:long": {
   "@type" : "http://www.w3.org/2001/XMLSchema#float",
   "@value" : "98.2"
 }
},
{
 "@id": "p2ont:Sensor_1",
 "@type": "saref:Sensor",
 "saref:IsUsedFor": {
   "@id": "p2ont:position"
 },
 "saref:hasFunction": {
   "@id": "p2ont:sensingFunction"
 },
 "saref:makesMeasurement": {
   "@id": "p2ont:Measurement_1"
 }
},
{
 "@id": "p2ont:Measurement_1",
 "@type": "saref:Measurement",
 "saref:hasTimestamp": {
   "@id": "p2ont:Time_1"
 },
 "saref:hasValue": {
   "@id": "p2ont:PositionMeasurementValue"
 },
 "saref:relatesToProperty": {
   "@id": "p2ont:positionProperty"
 }
},
{
 "@id": "p2ont:Time_1",
 "@type": "time:Instant",
 "time:inXSDDateTime": {
   "@type" : "http://www.w3.org/2001/XMLSchema#dateTime",
   "@value" : "2017-05-08T13:48:18"
 }
},
{
 "@id": "p2ont:sensingFunction",
 "@type": "saref:SensingFunction"
},
{
 "@id": "p2ont:positionProperty",
 "@type": "saref-ps:PositionProperty"
}

The corresponding diagram (according to notation):

Input RDF

RDF input

The resultant RDF should be:

{
   "@id" : "_:b0",
   "@type" : "InterIoT:central#Position"
 }, {
   "@id" : "p2ont:PositionMeasurementValue",
   "@type" : [ "sosa:Result", "http://www.opengis.net/ont/geosparql#Geometry" ],
   "http://www.opengis.net/ont/geosparql#asWKT" : {
     "@type" : "http://www.opengis.net/def/sf/wktLiteral",
     "@value" : "Point(52.3 98.2)"
   }
 }, {
   "@id" : "p2ont:Measurement_1",
   "@type" : "sosa:Observation",
   "sosa:hasResult" : {
     "@id" : "p2ont:PositionMeasurementValue"
   },
   "sosa:madeBySensor" : {
     "@id" : "p2ont:Sensor_1"
   },
   "sosa:observedProperty" : {
     "@id" : "_:b0"
   },
   "sosa:resultTime" : {
     "@type" : "xsd:dateTime",
     "@value" : "2017-05-08T13:48:18"
   }
 }
],
 "@id" : "InterIoTMsg:payload"
}

The corresponding resultant graph is:

Input RDF

RDF output

Please note, that not all part of RDF graph are translated. Some parts will be left untouched as in input graph. The aforementioned code snippet and image present only part of the RDF graph that is a result of the translation.

Let us know analyze step by step an alignment that will allow to translate part of the input RDF graph into aforementioned output RDF graph.

<Alignment
       xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
       xmlns:wgs84_pos="http://www.w3.org/2003/01/geo/wgs84_pos#"
       xmlns:sripas="http://www.inter-iot.eu/sripas#"
       xmlns="http://www.inter-iot.eu/sripas#"
       xmlns:sosa="http://www.w3.org/ns/sosa/"
       xmlns:geosparql="http://www.opengis.net/ont/geosparql#"
       xmlns:saref="https://w3id.org/saref#"
       xmlns:saref-ps="http://ontology.tno.nl/saref/positionsensor#"
       xmlns:time="http://www.w3.org/2006/time#"
       xmlns:co="http://inter-iot.eu/central"
       xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
       xmlns:geo-sf="http://www.opengis.net/def/sf/"
       name="alignDemo_P2_CO" version="1.0" creator="P2_admin">
   <onto1>
       <Ontology about="http://platform2.eu/sensors#">
           <formalism>
               <Formalism name="OWL2.0" uri="http://www.w3.org/2002/07/owl#"/>
           </formalism>
       </Ontology>
   </onto1>
   <onto2>
       <Ontology about="http://www.inter-iot.eu/central">
           <formalism>
               <Formalism name="OWL2.0" uri="http://www.w3.org/2002/07/owl#"/>
           </formalism>
       </Ontology>
   </onto2>
   <steps>
       <step order="1" cell="cell1"/>
       <step order="2" cell="cell2"/>
       <step order="3" cell="cell3"/>
   </steps>
   <map>
       <Cell id="cell1">
           <entity1>
               <sripas:node_CTZ>
                   <saref:makesMeasurement>
                       <sripas:node_CTC>
                           <rdf:type rdf:resource="&saref;Measurement"/>
                           <saref:hasValue>
                               <sripas:node_CTA/>
                           </saref:hasValue>
                           <saref:hasTimestamp>
                               <sripas:node_CTB>
                                   <time:inXSDDateTime>
                                       <sripas:node_x/>
                                   </time:inXSDDateTime>
                               </sripas:node_CTB>
                           </saref:hasTimestamp>
                       </sripas:node_CTC>
                   </saref:makesMeasurement>
               </sripas:node_CTZ>
           </entity1>
           <entity2>
               <sripas:node_CTC>
                   <rdf:type rdf:resource="&sosa;Observation"/>
                   <sosa:observedProperty>
                       <rdf:Description>
                           <rdf:type rdf:resource="&co;Position"/>
                       </rdf:Description>
                   </sosa:observedProperty>
                   <sosa:madeBySensor>
                       <sripas:node_CTZ/>
                   </sosa:madeBySensor>
                   <sosa:hasResult>
                       <sripas:node_CTA/>
                   </sosa:hasResult>
                   <sosa:resultTime>
                       <sripas:node_x/>
                   </sosa:resultTime>
               </sripas:node_CTC>
           </entity2>
           <relation>=</relation>
           <typings>
               <typing about="&sripas;node_x" datatype="&xsd;dateTime"/>
           </typings>
       </Cell>
       <Cell id="cell2">
           <entity1>
               <sripas:node_CTX>
                   <rdf:type rdf:resource="&wgs84_pos;Point"/>
                   <wgs84_pos:lat>
                       <sripas:node_x/>
                   </wgs84_pos:lat>
                   <wgs84_pos:long>
                       <sripas:node_y/>
                   </wgs84_pos:long>
               </sripas:node_CTX>
           </entity1>
           <entity2>
               <sripas:node_CTX>
                   <rdf:type rdf:resource="&geosparql;Geometry"/>
                   <rdf:type rdf:resource="&sosa;Result"/>
                   <geosparql:asWKT>
                       <sripas:node_z/>
                   </geosparql:asWKT>
               </sripas:node_CTX>
           </entity2>
           <relation>=</relation>
           <sripas:transformation>
               <function about="str">
                   <param order="1" about="&sripas;node_x"/>
                   <return about="&sripas;node_sx"/>
               </function>
               <function about="str">
                   <param order="1" about="&sripas;node_y"/>
                   <return about="&sripas;node_sy"/>
               </function>
               <function about="concat">
                   <param order="1" val="Point("/>
                   <param order="2" about="&sripas;node_sx"/>
                   <param order="3" val=" "/>
                   <param order="4" about="&sripas;node_sy"/>
                   <param order="5" val=")"/>
                   <return about="&sripas;node_z"/>
               </function>
           </sripas:transformation>
           <filters>
               <filter about="&sripas;node_x" datatype="http://www.w3.org/2001/XMLSchema#float"/>
               <filter about="&sripas;node_y" datatype="http://www.w3.org/2001/XMLSchema#float"/>
               <filter about="&sripas;node_sx" datatype="http://www.w3.org/2001/XMLSchema#string"/>
               <filter about="&sripas;node_sy" datatype="http://www.w3.org/2001/XMLSchema#string"/>
           </filters>
           <typings>
               <typing about="&sripas;node_z" datatype="&geo-sf;wktLiteral"/>
           </typings>
       </Cell>
   </map>
</Alignment>

The translation includes two steps as indicated in:

<steps>
       <step order="1" cell="cell1"/>
       <step order="2" cell="cell2"/>
</steps>

The first step is defined as:

 <Cell id="cell1">
           <entity1>
               <sripas:node_CTZ>
                   <saref:makesMeasurement>
                       <sripas:node_CTC>
                           <rdf:type rdf:resource="&saref;Measurement"/>
                           <saref:hasValue>
                               <sripas:node_CTA/>
                           </saref:hasValue>
                           <saref:hasTimestamp>
                               <sripas:node_CTB>
                                   <time:inXSDDateTime>
                                       <sripas:node_x/>
                                   </time:inXSDDateTime>
                               </sripas:node_CTB>
                           </saref:hasTimestamp>
                       </sripas:node_CTC>
                   </saref:makesMeasurement>
               </sripas:node_CTZ>
           </entity1>
           <entity2>
               <sripas:node_CTC>
                   <rdf:type rdf:resource="&sosa;Observation"/>
                   <sosa:observedProperty>
                       <rdf:Description>
                           <rdf:type rdf:resource="&co;Position"/>
                       </rdf:Description>
                   </sosa:observedProperty>
                   <sosa:madeBySensor>
                       <sripas:node_CTZ/>
                   </sosa:madeBySensor>
                   <sosa:hasResult>
                       <sripas:node_CTA/>
                   </sosa:hasResult>
                   <sosa:resultTime>
                       <sripas:node_x/>
                   </sosa:resultTime>
               </sripas:node_CTC>
           </entity2>
           <relation>=</relation>
           <typings>
               <typing about="&sripas;node_x" datatype="&xsd;dateTime"/>
           </typings>
       </Cell>

Here, a an input structure of RDF with device that makes a measurement is specified according to SAREF ontology. Measurement has indicated properties for value and time. This structure is translated to observation made by sensor in SSN/SOSA ontology. In this case observation is also characterized by result value and result time. Note, that instance representing result is reused (the same URI) but it's type is translated. The entity stored in variable node_CTZ representing SAREF device is placed in a different position in output graph - it's value of sosa:madeBySensor property.

In this step we also add information about observed property that is related to SOSA observation with sosa:observedProperty. Here, we generate a blank node of type &co;Position. This is class is assumed to be a subclass of ssn:ObservableProperty in SSN/SOSA ontology, but is specialized as property related to geospatial position. Note that the first step defines a large transformation, however the same result can be achived by applying several more simple consecutive steps. If the input RDF graph is stable when it comes to structure then large part of it can be translated in one step.

The SPARQL update for the above cell is:

DELETE {
  ?node_CTZ <https://w3id.org/saref#makesMeasurement> ?node_CTC.
  ?node_CTB <http://www.w3.org/2006/time#inXSDDateTime> ?node_x.
  ?node_CTC <https://w3id.org/saref#hasTimestamp> ?node_CTB.
  ?node_CTC <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/saref#Measurement>.
  ?node_CTC <https://w3id.org/saref#hasValue> ?node_CTA.
} INSERT {
  _:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://inter-iot.eu/central#Position>.
  ?node_CTC <http://www.w3.org/ns/sosa/resultTime> ?node_x_typed.
  ?node_CTC <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/ns/sosa/Observation>.
  ?node_CTC <http://www.w3.org/ns/sosa/observedProperty> _:b0.
  ?node_CTC <http://www.w3.org/ns/sosa/madeBySensor> ?node_CTZ.
  ?node_CTC <http://www.w3.org/ns/sosa/hasResult> ?node_CTA.
} WHERE {
  ?node_CTZ <https://w3id.org/saref#makesMeasurement> ?node_CTC.
  ?node_CTB <http://www.w3.org/2006/time#inXSDDateTime> ?node_x.
  ?node_CTC <https://w3id.org/saref#hasTimestamp> ?node_CTB.
  ?node_CTC <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://w3id.org/saref#Measurement>.
  ?node_CTC <https://w3id.org/saref#hasValue> ?node_CTA.
  BIND(STRDT(STR(?node_x), <http://www.w3.org/2001/XMLSchema#dateTime>) AS ?node_x_typed)
}

The RDF graph after applying this cell is:

RDF after applying *cell1*

RDF after cell1

Input and output RDF