Ontology Modeling with SHACL: Defining Constraint Components

Ontology Modeling with SHACL: Defining Constraint Components

In this part of our SHACL tutorial, we will show how SHACL itself can be extended. In the previous article, we have shown how complex constraints can be expressed using SPARQL queries. Now we will generalize such queries into reusable templates. These templates are wrapped into so-called Constraint Components which can then be used just like the built-in constraint types such as sh:minCount and sh:datatype.

Use Case

In the first Getting Started article of this tutorial, we have introduced a simple ontology to represent Chess games and the constraints on its pieces. As our running example in this article we want to express the following constraint:

There cannot be two pieces on the same square of the same board.

The following Game should be flagged as invalid, as it has two pieces on "b1".

ex:ExampleGame
    a shess:Game ;
    shess:piece [
        a shess:King ;
        shess:color shess:White ;
        shess:square "a1" ;
    ] ;
    shess:piece [
        a shess:King ;
        shess:color shess:Black ;
        shess:square "b1" ;
    ] ;
    shess:piece [
        a shess:Queen ;
        shess:color shess:Black ;
        shess:square "b1" ;
    ] .        

Finding these duplicates is reasonably straight-forward in SPARQL:

SELECT *
WHERE {
    $this shess:piece ?piece1 .
    ?piece1 shess:square ?square .
    ?piece2 shess:square ?square .
    $this shess:piece ?piece2 .
    FILTER (?piece1 != ?piece2) .
}        

Assuming $this points as the Game instance, this query will try to find two (distinct) pieces that have the same square using a join on the variable ?square. Note that the query also makes sure that both pieces are in the same Game as values of shess:piece.

Generalizing the SPARQL Query

We could now turn this into a SPARQL-based constraint just like in the previous article. However, it feels like this constraint pattern may be occurring in other scenarios too. For example:

  • All players in the same rugby team must have a different jersey number
  • All towns in the same state must have a unique name

All of these scenarios could be expressed using a similar SPARQL query, if we only substitute the property names. For example, the property shess:piece could be substituted with ex:teamMember and shess:square would become ex:jerseyNumber.

Instead of having to repeat different variations of the same SPARQL query, it would be ideal if we could define something like a template where we only need to substitute certain RDF nodes in the query. This is exactly what SPARQL-based constraint components can do.

Constraint Components

The SHACL standard defines the concept of Constraint Components as the available constraint types. Each of these components is activated by a constraint parameter. For example, sh:MinCountConstraintComponent is activated when a shape contains a value for the parameter sh:minCount. These are the built-in constraint types, but anyone can define new components.

The syntax for defining new constraint components looks as follows:

shess:UniquePropertyConstraintComponent
    a sh:ConstraintComponent ;
    rdfs:label "Unique property constraint component" ;
    sh:labelTemplate "Values of {?uniqueProperty} must be unique" ;
    sh:message "Value {?value} is not unique" ;
    sh:parameter [
        a sh:Parameter ;
        sh:path shess:uniqueProperty ;
        sh:nodeKind sh:IRI ;
    ] ;
    sh:propertyValidator shess:UniquePropertyValidator .        

This declares a parameter shess:uniqueProperty which should link to the IRI of the property that we want to validate uniqueness of.

Validators

The constraint component also links to a Validator that instructs a SHACL engine how to validate the focus nodes based on the provided parameter value(s):

shess:UniquePropertyValidator
    a sh:SPARQLSelectValidator ;
    rdfs:label "Unique property validator" ;
    sh:select """
        SELECT $this ?value
        WHERE {
            $this $PATH ?node1 .
  	    ?node1 $uniqueProperty ?value .
  	    ?node2 $uniqueProperty ?value .
  	    $this $PATH ?node2 .
            FILTER (?node1 != ?node2) .
        }""" .        

This is now a generalization of the original SPARQL query, in which the variable $uniqueProperty is a placeholder for the specific property such as shess:square, and $PATH is a placeholder for the property shess:piece.

Using the new Constraint Component

Once this constraint component has been declared, it can be used as follows:

shess:Game
    a dash:ShapeClass ;
    ...
    sh:property shess:Game-piece .

shess:Game-piece
    a sh:PropertyShape ;
    sh:path shess:piece ;
    sh:class shess:Piece ;
    sh:minCount 2 ;
    sh:name "pieces" ;
    shess:uniqueProperty shess:square .        

The property shape for shess:piece now has an extra property shess:uniqueProperty that instructs a SHACL engine that for all values of shess:piece, their values of shess:square must be unique within the current shess:Game instance. No two chess pieces can be on the same square.

Note that the constraint component is now also independent from the specific Chess example, and would also work for something like this:

ex:RugbyTeam
    a dash:ShapeClass ;
    sh:property ex:RugbyTeam-member .

ex:RugbyTeam-member
    a sh:PropertyShape ;
    sh:path ex:member ;
    sh:class ex:Player ;
    shess:uniqueProperty ex:jerseyNumber .        

Given that the component is more general than Chess, we should probably move it to some other namespace. For example, the DASH namespace includes library of generic, reusable constraint components such as dash:uniqueValueForClass or dash:nonRecursive. All these are backed by SPARQL queries and completely declarative, which means that any SHACL engine with SHACL-SPARQL support will know how to process them.

Summary and Outlook

This article has illustrated how SHACL itself can be extended with new constraint types. All you need to do is declare the parameter(s) and the SPARQL query template that encapsulate the logic behind such constraints.

As a result, ontology developers who are not necessarily experts in SPARQL can tap into constraint types that other people have defined. Furthermore, ontologies and shapes can use a compact declarative syntax instead of having to repeat similar SPARQL queries over and over again.

This is a capability that goes way beyond what related standards such as OWL can do. While the expressiveness of OWL was defined by a committee that hand-picked certain types of restrictions, anyone is able to define new SHACL constraint components in a declarative manner.

要查看或添加评论,请登录

Holger Knublauch的更多文章

社区洞察

其他会员也浏览了