Applying inference to a model

Use a SHACL-AF rule to copy each person’s name into a display-name property, then validate the extended model. Install Shifty as described in Install Shifty.

Create a rule and data file

Save this as rules.ttl:

@prefix ex: <http://example.org/> .
@prefix sh: <http://www.w3.org/ns/shacl#> .

ex:PersonShape a sh:NodeShape ;
    sh:targetClass ex:Person ;
    sh:rule [
        a sh:TripleRule ;
        sh:subject sh:this ;
        sh:predicate ex:displayName ;
        sh:object [ sh:path ex:name ] ;
    ] ;
    sh:property [
        sh:path ex:displayName ;
        sh:minCount 1 ;
    ] .

The rule selects each ex:Person and adds an ex:displayName triple using their ex:name value. The property constraint requires a display name.

Save this as data.ttl:

@prefix ex: <http://example.org/> .

ex:alice a ex:Person ; ex:name "Alice" .

Run inference

Run this beside the two files:

shifty infer --shapes rules.ttl --data data.ttl
inferred 1 triple(s):
  <http://example.org/alice> <http://example.org/displayName> "Alice"

The output lists the new triple. Rules run repeatedly until they produce no further additions.

In Python, retrieve the extended graph:

import shifty

result = shifty.infer("data.ttl", "rules.ttl")
print("new triples:", result.inferred_count)
graph = result.graph()
new triples: 1

result.graph() contains both the original data and the derived triples. To save it, call graph.serialize("extended.ttl", format="turtle").

Validate with the rule

Validation runs inference by default, so the derived display name satisfies the property constraint:

shifty validate --shapes rules.ttl --data data.ttl
conforms: true

Add --no-infer and validation fails because the original data has no ex:displayName. Python has the same default:

import shifty

for infer in (True, False):
    conforms, _, _ = shifty.validate("data.ttl", "rules.ttl", infer=infer)
    print(f"infer={infer}: conforms={conforms}")
infer=True: conforms=True
infer=False: conforms=False

Continue with Run SHACL-AF inference for in-place RDFLib updates and other inference options, or Feature support for supported rules.