IPSM Alignment Format (IPSM-AF)

Alignment can be interpreted as a set of uni-directional mappings for transforming input RDF graph into output RDF graph. It is persisted in IPSM Alignment Format (IPSM-AF) that is based on a well known Alignment API Format.

!Note! IPSM from version 0.6 supports IPSM-AF persisted as RDF/XML. Prior versions supported alignments persisted as XML. In RDF/XML persisted version alignments cell can contain RDF/XML or Turtle syntax. The convertes from old IPSM-AF format and from cells in RDF/XML to Turle syntax are available (see REST API paths).

Namespaces

Namespaces Suggested prefix
http://www.inter-iot.eu/sripas# sripas
http://www.inter-iot.eu/sripas:node_ var
http://www.inter-iot.eu/sripas:pred_ pred
http://knowledgeweb.semanticweb.org/heterogeneity/alignment# align
http://purl.org/dc/elements/1.1/ dcelem
http://exmo.inrialpes.fr/align/ext/1.0/# exmo

IPSM-AF Structure in XML (DEPRECATED)

<Alignment id="align_id" version="align_version" creator="align_creator" description="align_desc">
<onto1> 
    <align:location>[source ontology location]</align:location>
    <align:formalism>
        <align:Formalism align:name="[source ontology formalism name]" align:uri="[source ontology formalism URI]" />
    </align:formalism>
</onto1>
<onto2>
    <align:location>[target ontology location]</align:location>
    <align:formalism>
        <align:Formalism align:name="[target ontology formalism name]" align:uri="[target ontology formalism URI]" />
    </align:formalism>
</onto2>
<steps>
 <step order="[cell order]" cell="[cell id]"/>
 { more steps }
</steps>
<map>
 <Cell id="[cell id]">
   <entity1> { source RDF pattern } </entity1>
   <entity2> { target RDF pattern } </entity2>
   <transformation>
     { functional constraints }
   </transformation>
   <filters> { datatype constraints } </filters>
   <typings> { typing info } </typings>
 </Cell>
 { more Cells }
</map>
</Alignment>

IPSM-AF Structure in XML/RDF

<?xml version='1.0' encoding='utf-8' standalone='no'?>
<rdf:RDF xmlns="http://www.inter-iot.eu/sripas#"
    {other xml namespaces} >
<align:Alignment>
    <dcelem:title>[alignment title]</dcelem:title>
    <exmo:version>[alignment version]</exmo:version>
    <dcelem:creator>[alignment creator]</dcelem:creator>
    <dcelem:description>[alignemnt description]</dcelem:description>

    <align:xml>yes</align:xml>
    <align:level>2IPSM</align:level>
    <align:type>**</align:type>

    <align:method>[method]</align:method>
    <dcelem:date>[date]</dcelem:date>

     <sripas:cellFormat>
            <iiot:DataFormat rdf:about="http://inter-iot.eu/sripas#rdfxml" />
        </sripas:cellFormat>

    <align:onto1>
        <align:Ontology rdf:about="[source ontology uri]">
            <align:location>[source ontology location]</align:location>
            <align:formalism>
                <align:Formalism align:name="[source ontology formalism name]" align:uri="[source ontology formalism URI]" />
            </align:formalism>
        </align:Ontology>
    </align:onto1>
    <align:onto2>
        {target ontology information}
    </align:onto2>

    <sripas:steps rdf:parseType="Literal">
        <sripas:step sripas:order="[cell order]" sripas:cell="[cell id]"/>
        { more steps }
    </sripas:steps>

     <align:map>
         {alignment cell 1}
    </align:map>
         ...
       <align:map>
         {alignment cell n}
    </align:map>
</align:Alignment>
</rdf:RDF>

The most crucial part - translation logic - is contained inside cell elements. Each cell is applied in an order specified in the steps element.

Metadata

The following table contains descriptions of fields treated as metadata - they are parsed when storing alignments in INTER-IoT semantic repository, but not in the translation process itself.

Element/Attribute Meaning
dcelem:title Name of the alignment e.g. SSN_Observation_SAREF_Mesurement
exmo:version Version of the alignment e.g. 1.0
dcelem:creator Author of the alignment
dcelem:description Comment on what is the scope/aim of the alignment
dcelem:date Derived from Alignment API. Timestamp of an event in the lifecycle of the alignment e.g. creation date (ISO8601 format)
align:xml Derived from Alignment API. Default value: yes
align:level Derived from Alignment API. Default value: 2IPSM
align:method Derived from Alignment API. Default value: manual
align:type Derived from Alignment API. Default value: **

IPSM-AF is compatible with Alignment API format so it supports Alignment API extension labels that provide the opportunity for applications to attach information which is not part of the format but can hold valuable metadata information.

Alignment cells

Each alignment cell represents one "step" in the translation process. The steps in order in which they should be applied are specified in the sripas:steps element.

<sripas:steps rdf:parseType="Collection">
    <sripas:step sripas:order="1" sripas:cell="Cell_Id_1"/>
    <sripas:step sripas:order="2" sripas:cell="Cell_Id_2"/>
    <sripas:step sripas:order="3" sripas:cell="Cell_Id_3"/>
    ...
</sripas:steps>

The order of steps is alignment specific i.e. alignment with the same cell logic but executed in different order should be persisted as a new alignment.

The cell applies SPARQL UPDATE to the RDF graph resulting from previous step (or source graph in case of first step). The SPARQL UPDATE statement is generated from "triples pattern" found in elements entity1, entity2, transformations, typings.

The following example can be read as subject var:CTA is related to object var:CTB with predicate sosa:madeBySensor. Prefix var (http://www.inter-iot.eu/sripas:node_) with arbitrary name is used to denote variables that can be reused e.g. to later specify content of entity2.

<var:CTA>
      <sosa:madeBySensor>
          <var:CTB/>
      </sosa:madeBySensor>
<var:CTA>

If additionally, we want to restrict on type, the example can be changed to the following:

<var:CTA>
    <rdf:type rdf:resource="&sosa;Observation"/>
    <sosa:madeBySensor>
        <var:CTB>
            <rdf:type rdf:resource="&sosa;Sensor"/>
        </var:CTB>
    </sosa:madeBySensor>
<var:CTA>

This time we are not only matching two entities related with a property but entities of specified type related with a property. Matched RDF triple will have subject of type sosa:Observation and object of type sosa:Sensor.

The RDF graph structure pattern can be more complex e.g.

<var:CTX>
   <rdf:type rdf:resource="http://platform1.eu/sensors#PositionObservation" />
   <ssn:observationResult>
       <var:CTY>
           <rdf:type rdf:resource="http://platform1.eu/sensors#PositionSensorOutput" />
           <ssn:hasValue>
               <var:CTU/>
           </ssn:hasValue>
           <ssn:isProducedBy>
               <var:CTS/>
           </ssn:isProducedBy>
       </svar:CTY>
   </ssn:observationResult>
   <ssn:observationResultTime>
       <var:CTZ/>
   </ssn:observationResultTime>
   <ssn:featureOfInterest>
       <var:CTW/>
   </ssn:featureOfInterest>
   <ssn:observedBy>
       <var:CTV/>
   </ssn:observedBy>
</var:CTX>

Here, we want to match all instances of http://platform1.eu/sensors#PositionObservation class that have asserted properties ssn:observationResult, ssn:observationResultTime, ssn:featureOfInterest, ssn:observedBy. Value of ssn:observationResult is an entity of type http://platform1.eu/sensors#PositionSensorOutput with asserted property ssn:hasValue.

Lets assume that we want to translate the above structure into:

<var:CTX>
   <rdf:type rdf:resource="&sosa;Observation"/>
   <sosa:observedProperty>
       <rdf:Description>
           <rdf:type rdf:resource="&co;Position" />
       </rdf:Description>
   </sosa:observedProperty>
   <sosa:hasFeatureOfInterest>
       <var:CTW/>
   </sosa:hasFeatureOfInterest>
   <sosa:hasResult>
       <var:CTU/>
   </sosa:hasResult>
   <sosa:madeBySensor>
       <var:CTS/>
   </sosa:madeBySensor>
   <sosa:resultTime>
       <var:CTZ/>
   </sosa:resultTime>
</var:CTX>

This translated RDF graph has the same information content, however it is expressed in SSN/SOSA ontology and not SSN as it was in the case of input RDF graph. In IPSM the graph pattern from entity1 and entity2 is internally transformed into the following SPARQL UPDATE statement.

DELETE {
      ?node_CTX <http://purl.oclc.org/NET/ssnx/ssn#observedBy> ?node_CTV.
  ?node_CTX <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://platform1.eu/sensors#PositionObservation>.
    ?node_CTX <http://purl.oclc.org/NET/ssnx/ssn#observationResult> ?node_CTY.
    ?node_CTX <http://purl.oclc.org/NET/ssnx/ssn#observationResultTime> ?node_CTZ.
    ?node_CTX <http://purl.oclc.org/NET/ssnx/ssn#featureOfInterest> ?node_CTW.
    ?node_CTY <http://purl.oclc.org/NET/ssnx/ssn#isProducedBy> ?node_CTS. 
    ?node_CTY <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://platform1.eu/sensors#PositionSensorOutput>.
    ?node_CTY <http://purl.oclc.org/NET/ssnx/ssn#hasValue> ?node_CTU.
} 

INSERT {
      _:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://inter-iot.eu/central#Position>.

    ?node_CTX <http://www.w3.org/ns/sosa/resultTime> ?node_CTZ.

    ?node_CTX <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/ns/sosa/Observation>.
    ?node_CTX <http://www.w3.org/ns/sosa/observedProperty> _:b0.
    ?node_CTX <http://www.w3.org/ns/sosa/hasFeatureOfInterest> ?node_CTW.
     ?node_CTX <http://www.w3.org/ns/sosa/hasResult> ?node_CTU.
    ?node_CTX <http://www.w3.org/ns/sosa/madeBySensor> ?node_CTS.
} 
WHERE {
      ?node_CTX <http://purl.oclc.org/NET/ssnx/ssn#observedBy> ?node_CTV.
    ?node_CTX <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://platform1.eu/sensors#PositionObservation>. 
    ?node_CTX <http://purl.oclc.org/NET/ssnx/ssn#observationResult> ?node_CTY.
     ?node_CTX <http://purl.oclc.org/NET/ssnx/ssn#observationResultTime> ?node_CTZ.
    ?node_CTX <http://purl.oclc.org/NET/ssnx/ssn#featureOfInterest> ?node_CTW. 
    ?node_CTY <http://purl.oclc.org/NET/ssnx/ssn#isProducedBy> ?node_CTS.
    ?node_CTY <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://platform1.eu/sensors#PositionSensorOutput>.
    ?node_CTY <http://purl.oclc.org/NET/ssnx/ssn#hasValue> ?node_CTU.

Generating blank nodes in target RDF graph

In the SPARQL UPDATE statement from the previous subsection one can see that, if necessary, blank nodes can be generated.

<sripas:node_CTX>
   <rdf:type rdf:resource="&sosa;Observation"/>
   <sosa:observedProperty>
       <rdf:Description>
           <rdf:type rdf:resource="&co;Position" />
       </rdf:Description>
   </sosa:observedProperty>
  </sripas:node_CTX>

In this case the entity being the value of sosa:observedProperty is a blank node with type &co;Position. It is achieved by specifying rdf:Description.

Variables, Filters and Typings

From the aforementioned examples, it can be seen that alignment format allows for the usage of variables that can be placed as subjects, predicates or objects in RDF triples. It is assumed that variables representing subjects and objects are named node_[var name] and are declared in sripas namespace. Variables representing predicates are named pred_[var name] and are declared in sripas namespace as well. There are situations in which we want to explicitly restrict on a variables type, or specifiy type of a value returned for a function represented by a variable. In the IPSM-AF there are two elements that allow to do this: filters and typings. Filters are used to declare types of variables from entity1 and variable being input to transformations. Typyings allow to specify type of values returned from transformations.

<sripas:filters rdf:parseType="Literal">
   <sripas:filter about="http://www.inter-iot.eu/sripas#node_x" datatype="http://www.w3.org/2001/XMLSchema#float"/>
</sripas:filters>

The above filter element is transformed into:

FILTER( datatype(?node_x) = <http://www.w3.org/2001/XMLSchema#float> )

<sripas:typings rdf:parseType="Literal">
   <sripas:typing about="http://www.inter-iot.eu/sripas#node_z" datatype="http://www.opengis.net/def/sf/wktLiteral"/>
</sripas:typings>

The above typing element is transformed into:

BIND(STRDT(STR(?node_z), <http://www.opengis.net/def/sf/wktLiteral>) AS ?node_z_typed)

Transformations

The IPSM-AF allows to perform transformation on variables by calling functions. These are by default SPARQL functions (see https://www.w3.org/TR/sparql11-query/#SparqlOps), but can be as well external functions implemented as part of IPSM, or in the library available on the classpath (with respect to Jena ARQ Extensions). IPSM uses Jena library that support SPARQL 1.1 - these are possible restrictions on which functions are available. Note that, SPARQL imports a subset of the XPath constructor functions defined in https://www.w3.org/TR/xpath-functions/. The most basic functions that can be applied are just simple operators: +,-,*,/.

Each function call is declared in the sripas:transformation element, inside which function elements are nested. Each function element represents one call of a specified function that should be applied in the translation process. The following example represents transformation equivalent to multiplying a value stored in a node_CTY variable and a constant, with a result stored in node_CTZ variable. Additionally, in the following snippet we declare datatypes of the variables and constant.

<sripas:transformation rdf:parseType="Literal">
   <sripas:function about="*">
       <sripas:param order="1" about="http://www.inter-iot.eu/sripas#node_CTY"/>
       <sripas:param order="2" val="0.45" datatype="http://www.w3.org/2001/XMLSchema#double"/>
       <sripas:return about="http://www.inter-iot.eu/sripas#node_CTZ"/>
   </sripas:function>
</sripas:transformation>
<sripas:typings rdf:parseType="Literal">
   <sripas:typing about="http://www.inter-iot.eu/sripas#node_CTY" datatype="http://www.w3.org/2001/XMLSchema#double"/>
   <sripas:typing about="http://www.inter-iot.eu/sripas#node_CTZ" datatype="http://www.w3.org/2001/XMLSchema#double"/>
</sripas:typings>

Each function element has an about attributes in which an operator, SPARQL function name or name (with package) to the external function is given. Additionally, nested elements are included for function parameters and return value. Parameters have an order attribute which indicates in what order they are passed to the function. Parameters can be of two types: constants and variables. The latter have attribute val indicating specific value and datatype indicating type of data with respect to XSD datatypes. The former have about attribute in which the name of the variable is specified. Functions can take as input, output of other functions e.g.:

<sripas:transformation rdf:parseType="Literal">
   <sripas:function about="str">
       <param order="1" about="http://www.inter-iot.eu/sripas#node_x"/>
       <return about="http://www.inter-iot.eu/sripas#node_sx"/>
   </sripas:function>
   <sripas:function about="str">
       <sripas:param order="1" about="http://www.inter-iot.eu/sripas#node_y"/>
       <sripas:return about="http://www.inter-iot.eu/sripas#node_sy"/>
   </sripas:function>
   <sripas:function about="concat">
       <sripas:param order="1" val="Point("/>
       <sripas:param order="2" about="http://www.inter-iot.eu/sripas#node_sx"/>
       <sripas:param order="3" val=" "/>
       <sripas:param order="4" about="http://www.inter-iot.eu/sripas#node_sy"/>
       <sripas:param order="5" val=")"/>
       <sripas:return about="http://www.inter-iot.eu/sripas#node_z"/>
   </sripas:function>
</sripas:transformation>
<sripas:filters rdf:parseType="Literal">
   <sripas:filter about="http://www.inter-iot.eu/sripas#node_x" datatype="http://www.w3.org/2001/XMLSchema#float"/>
   <sripas:filter about="http://www.inter-iot.eu/sripas#node_y" datatype="http://www.w3.org/2001/XMLSchema#float"/>
   <sripas:filter about="http://www.inter-iot.eu/sripas#node_sx" datatype="http://www.w3.org/2001/XMLSchema#string"/>
   <sripas:filter about="http://www.inter-iot.eu/sripas#node_sy" datatype="http://www.w3.org/2001/XMLSchema#string"/>
   <sripas:filter about="http://www.inter-iot.eu/sripas#node_z" datatype="http://www.opengis.net/def/sf/wktLiteral"/>
</sripas:filters>
<sripas:typings rdf:parseType="Literal">
   <sripas:typing about="http://www.inter-iot.eu/sripas#node_z" datatype="http://www.opengis.net/def/sf/wktLiteral"/>
</sripas:typings>

In this example, first STR function is applied to cast values from variables x and y to string, and then CONCAT is applied to construct string with respect to wktLiteral format. Additionally, http://www.opengis.net/def/sf/wktLiteral datatype is assigned.