From RDF Data Shapes Working Group
Jump to: navigation, search

This page describes a potential addition to the SHACL spec, for section 10 (Entailment).

10.2 SHACL Rules

The property sh:rule can be used to link a shape with rules describing entailments that apply to all target nodes of the shape. The values of sh:rule must be IRIs or blank nodes. If a rule has a value for the property sh:construct, then this value must be a string literal that can be parsed into a valid SPARQL 1.1 CONSTRUCT query based on the prefix handling described in section 5.1.

SHACL engines are not required to support the sh:rule property. SHACL engines that do support rules SHOULD use them to perform entailments, so that the constructed triples are added to the input graph before it becomes the data graph of a validation process. The triples constructed by a rule consist of all results of executing the CONSTRUCT queries against the input graph. For the execution, the variable this is pre-bound with the target nodes of the shape, excluding the nodes that do not validate against the filter shapes of the shape. The triples constructed by a set of rules consist of the union of the triples constructed by each individual rule, including those constructed based on previously constructed triples. SHACL rule processing is undefined if the execution of rules causes an infinite number of entailments.

The following example illustrates a rule that creates an instance of ex:Customer for each SHACL instance of the class ex:Person that is a US citizen:

       a sh:Shape ;
       sh:targetClass ex:Person ;
       sh:filterShape ex:USCitizenShape ;
       sh:rule [
           sh:construct """
               CONSTRUCT {
                   ?customer a ex:Customer .
                   ?customer rdfs:label ?fullName .
               WHERE {
                   $this ex:firstName ?firstName .
                   $this ex:lastName  ?lastName .
                   BIND (CONCAT(ex:firstName, " ", ex:lastName) AS ?fullName) .
                   BIND (IRI(CONCAT(STR($this), "-Customer")) AS ?customer) .
       ] .

With the input graph

       a ex:Person ;
       ex:firstName "John" ;
       ex:lastName "Doe" .

executing the rule above would produce the following entailments

       a ex:Customer ;
       rdfs:label "John Doe" .