0

I'm trying to create a shacl based on the ontology that my organization is developing (in dutch): https://wegenenverkeer.data.vlaanderen.be/

The objects described have attributes (properties), that have a specified datatype. The datatype can a primitive (like string or decimal) or complex, which means the property will have properties itself (nested properties). For example: an asset object A will have an attribute assetId which is a complex datatype DtcIdentificator, which consists of two properties itself. I have succesfully created a shacl that validates objects by creating multiple shapes and nesting them.

I now run into the problem of what we call union datatypes. These are a special kind of complex datatypes. They are still nested datatypes: the attribute with the union datatypes will have multiple properties but only exactly zero or one of those properties may have a value. If the attribute has 2 properties with values, it is invalid. How can I create such a constraint in shacl?

Example (in dutch): https://wegenenverkeer.data.vlaanderen.be/doc/implementatiemodel/union-datatypes/#Afmeting%20verkeersbord A traffic sign (Verkeersbord, see https://wegenenverkeer.data.vlaanderen.be/doc/implementatiemodel/signalisatie/#Verkeersbord) can have a property afmeting (size) of the datatype DtuAfmetingVerkeersbord. If an asset A of this type would exist, I could define its size as (in dotnotation):

A.afmeting.rond.waarde = 700

-or-

A.afmeting.driehoekig.waarde = 400

Both are valid ways of using the afmeting property, however, if they are both used for the same object, this becomes invalid, as only one property of A.afmeting may have a value.

I have tried using the union constraint in shacl, but soon found out that that has nothing to do with what we call "union datatypes"

2 Answers2

1

I think the reason you are struggling is because this kind of problem is usually modelled differently. Basically you have different types of Traffic signs and these signs can have measurements. With the model as you described, A.afmeting.rond.waarde captures 2 ideas using 1 property: (a) the type and (b) the size. From your question, this seems to be the intend. However, this is usually not how this kind of problem is addressed.

A more intuitive design is for Traffic sign to have 2 different properties: (a) type and (b) a measurement. The Traffic sign types are achthoekig, driehoekig, etc. Then you can use SHACL to check that a traffic sign has either both or no properties for a traffic sign.

Henriette Harmse
  • 4,167
  • 1
  • 13
  • 22
  • Hi, thank you for your answer! I will quote and translate the definition of what we call a union datatype: "A union datatype is a datatype that behaves like an enumerated type except for the fact that the members of the enumaration may have different types." This was not clear from my example. Another valid definition for size would be: A.afmeting.vierhoekig.breedte.waarde = 400 A.afmeting.vierhoekig.hoogte.waarde = 400 The datatype of "vierhoekig" is a complex type itself. My point is: just defining the type isn't enough, defining the size is sometimes different – David Vlaminck Jan 09 '23 at 22:46
  • Yes. I suspected as much. In (b) if my answer it can refer to complex concept. The point is you still have 2 different properties. 1 for type and 1 for measurement details for your sign. In SHACL you enforce 1 type and based on type the specific shape defining the measurements for that type. – Henriette Harmse Jan 13 '23 at 19:27
  • Hi, I'm not saying this isn't a weird construction, but regardless, it is not my decision. I already got that "variable" type part working though, because it behaves just like a complex type (with nested properties). There is a property "rond" and a property "vierhoekig" and each of those have their own Shapes (and thus different types). The only issue I have is that only one of those properties may have a value. All other properties of this type can not have a value (they must all be NULL, or the equivalent of that) and I would like to enforce that with Shacl. Is that possible? – David Vlaminck Jan 17 '23 at 11:15
0

I have implemented a solution for this, using a combination of 'or' and 'and' constraints:

imel:DtuTestUnionTypeUnionConstraint a sh:NodeShape ;
     rdfs:comment "union constraint of https://wegenenverkeer.data.vlaanderen.be/ns/implementatieelement#DtuTestUnionType" ;
     sh:or ( [ sh:and ( [ sh:maxCount 0 ;
          sh:path imel:DtuTestUnionType.unionKwantWrd ]
          [ sh:maxCount 0 ;
          sh:path imel:DtuTestUnionType.unionString ] ) ]
     [ sh:and ( [ sh:minCount 1 ;
          sh:path imel:DtuTestUnionType.unionKwantWrd ]
          [ sh:maxCount 0 ;
          sh:path imel:DtuTestUnionType.unionString ] ) ]
     [ sh:and ( [ sh:maxCount 0 ;
          sh:path imel:DtuTestUnionType.unionKwantWrd ]
          [ sh:minCount 1 ;
          sh:path imel:DtuTestUnionType.unionString ] ) ] ) ;
     sh:targetObjectsOf imel:DtuTestUnionType .