SPIN Mini Profile

Draft for a minimum subset of SPIN for the RDF Shapes WG

Authors:
Holger Knublauch <holger@topquadrant.com> updated 23 July, 2014

Abstract

This document outlines a minimum sub-set of SPIN that tries to address some of the goals of the RDF Shapes working group (Charter).


Table of Contents

 

SPIN Vocabulary

Namespace prefixes used:

    sp : <http://spinrdf.org/sp#">
    spin : <http://spinrdf.org/spin#">
    spl : <http://spinrdf.org/spl#">

SPARQL CONSTRUCT queries are represented by blank nodes of the class sp:Construct with a property sp:text pointing at a SPARQL query string (all examples in Turtle):

    [
        a sp:Construct ;
        sp:text """
            CONSTRUCT {
                # ...
            }
            WHERE {
                # ...
            }
            """
    ]

SPIN constraints are SPARQL CONSTRUCT queries or corresponding template calls that are attached to an RDFS/OWL class via the property spin:constraint. Inside of those constraints, the variable ?this points at the instance of the class (and its subclasses) that is currently being evaluated. The queries construct instances of spin:ConstraintViolation for anything that shall be flagged as an error (or warning or whatever).

    ex:Person 
        a owl:Class ;
        spin:constraint [
            a sp:Construct ;
            sp:text """
                CONSTRUCT {
                    _:cv a spin:ConstraintViolation ;
                         spin:violationRoot ?this ;         # Optional
                         spin:violationPath ex:firstName ;  # Optional
                         rdfs:label "Same-sex marriage not permitted (in this model)"
                }
                WHERE {
                    ?this ex:spouse ?spouse .
                    ?this ex:gender ?gender .
                    ?spouse ex:gender ?spouseGender .
                    FILTER (?gender = ?spouseGender) .
                }
            """
        ]
    ]

SPIN templates are reusable SPARQL queries identified by an instance of spin:ConstructTemplate with a URI and a spin:body that can be parameterized with pre-bound variables. Each variable that is pre-bound must be declared by one instance of spl:Argument, where the spl:predicate points to the property that is instantiated to hold the actual argument. At query execution time, the predicates are mapped to named variables consisting of the local name of the spl:predicate. The following example declares a template ex:MinCardinality:

    ex:MinCardinality
      a       spin:ConstructTemplate ;
      rdfs:subClassOf 	spin:ConstructTemplates ;
      rdfs:comment "Checks whether ?this has at least ?count values for a given property ?predicate." ;
      rdfs:label "Min cardinality"^^xsd:string ;
      spin:constraint
              [ a       spl:Argument ;
                rdfs:comment "the minimum number of values expected" ;
                spl:predicate ex:count ;
                spl:valueType xsd:integer
              ] ;
      spin:constraint
              [ a       spl:Argument ;
                rdfs:comment "the property being restricted" ;
                spl:predicate ex:predicate ;
                spl:valueType rdf:Property
              ] ;
      spin:labelTemplate "at least {?count} values for {?predicate}"^^xsd:string ;
      spin:body
              [ a       sp:Construct ;
                sp:text """
                    CONSTRUCT {
                        _:cv a spin:ConstraintViolation ;
                            spin:violationRoot ?this ;
                            spin:violationPath ?predicate ;
                            rdfs:label ?label 
                    }
                    WHERE {
                        FILTER (ex:cardinality(?predicate) < ?count) .
                        BIND (CONCAT("The property ", xsd:string(?predicate), " must have at least ", ?count, " values") AS ?label ) .
                    }"""
              ] .

Templates such as the one above can be instantiated as values for spin:constraint (and similar properties). In the following Turtle example, instances of the class ex:Person are required to have at least one value for ex:firstName.

    ex:Person
        a owl:Class ;
        spin:constraint [
            a ex:MinCardinality ;
            ex:predicate ex:firstName ;
            ex:count 1 
        ]

Rules: The property spin:rule is similar to spin:constraint in that it links a class definition with CONSTRUCT queries or corresponding template calls. However in contrast to spin:constraint, rules may construct arbitrary new triples, or "inferences", and they are executed with a fix point algorithm until no further rules fire. In the following example, the values of ex:grandParent are derived to be the parents of the parents of the person ?this:

    ex:Person
        a owl:Class ;
        spin:rule [
           a sp:Construct ;
           sp:text """
               CONSTRUCT {
                   ?this ex:grandParent ?grandParent .
               }
               WHERE {
                   ?this ex:parent/ex:parent ?grandParent .
               }
           """
        ]

 

SPIN Standard Templates Library (SPL)

An agreed upon library of SPIN templates with a well-defined meaning should be defined to cover the most frequently needed use cases. This allows users of SPIN to define the structure of class definitions without even knowing SPARQL. It also allows tools to analyze the "shape" of class definitions to drive input fields or optimize SPARQL queries - tools can hard-code a certain understanding of those standard templates. Furthermore it would be possible to define syntactic sugar that produces those standard template calls.

SPIN has included two standard templates since its very early versions. spl:Attribute can be used to declare a property that is expected for a given class, including spl:valueType (range), spl:minCount and spl:maxCount to specify the expected cardinality of that property. Furthermore, spl:defaultValue can be specified to drive user interfaces and for other use cases. spl:Argument is similar but is used for properties that have either zero or more values, using spl:optional. Here is an example class definition using spl:Attribute:

    ex:Person
        a owl:Class ;
        spin:constraint [
            a spl:Attribute ;
            rdfs:comment "the first name of the person" ;
            spl:predicate ex:firstName ;
            spl:minCount 1 ;
            spl:valueType xsd:string ;
            spl:defaultValue "John"
        ] ;
        spin:constraint [
            a spl:Attribute ;
            rdfs:comment "the parent(s) of the person" ;
            spl:predicate ex:parent ;
            spl:minCount 0 ;
            spl:maxCount 2 ;
            spl:valueType ex:Person 
        ] ; 
        ...

Additional standard templates should be defined based on community needs. Note that anyone can add new templates, and they are all executed using the same unified mechanism.

 

SPIN RDF Syntax (Optional)

The original SPIN member submission includes a comprehensive RDF representation that allows SPARQL queries to be stored as triples. This has some advantages but may increase the implementation burden.

 

SPIN Functions (Optional)

The original SPIN member submission includes a mechanism to define new SPARQL functions based on other SPARQL (SELECT and ASK) queries. These functions are declared in a similar way as SPIN templates - they have a spin:body and declare the input arguments as spl:Arguments via spin:constraint. When called in a SPARQL query, the spin:body of the function gets executed with pre-bound variables for the arguments. This is a very powerful and relatively clean mechanism to extend SPARQL engines with reusable building blocks that make other queries (such as constraints and rules) easier to maintain and read.