The SPIN Standard Modules Library

October 20, 2009

Authors:
Holger Knublauch <holger@topquadrant.com>

Abstract

SPIN provides a mechanism to encapsulate SPARQL queries into reusable building blocks so that they can be shared on the Semantic Web. In particular, SPIN makes it possible to define new SPARQL functions and query templates together with definitions of their arguments. The SPIN Standard Modules Library (SPL) is a collection of such SPIN functions and templates that might be of general use. Among others, this library covers some common domain modeling patterns such as attribute declarations with cardinality and value range constraints. SPL also declares the standard SPARQL functions like != and bound.

Status of This Document

1.1.1

This document is part of the SPARQL Inferencing Notation (SPIN) specification.


Table of Contents

 

1 Introduction

The SPIN Standard Modules Library has been designed to provide a small collection of frequently needed SPARQL queries. Each query module in the SPL has a unified URI so that users don't need to reinvent the wheel when they require similar functionality in their own SPIN models.

Potentially such a library could comprise domain specific features such as geospatial functions, unit conversion, or mathematical utilities. However, in order to keep the SPL as small as possible, the focus of SPL is on domain modeling, i.e. on the language level similar to RDF Schema and OWL.

1.1 An Example

Here is an example use of the SPL template spl:Attribute (at a class definition in N3 notation):

    ex:Wine
      a       rdfs:Class ;
      rdfs:label "Wine"^^xsd:string ;
      spin:constraint
              [ a       spl:Attribute ;
                rdfs:comment "the color of the wine"^^xsd:string ;
                spl:predicate ex:color ;
                spl:minCount 1 ;
                spl:maxCount 1 ;
                spl:valueType ex:Color ;
                spl:defaultValue ex:Red
              ] .

The above example uses spin:constraint to link the class ex:Wine with a constraint on its property values. The constraint is an instance of the template spl:Attribute, and SPIN engines will substitute the template call with a parameterized version of the template's body. The generic body of the spl:Attribute template looks like:

    ASK
    WHERE {
        {
            FILTER (bound(?minCount) && 
                    (spl:objectCount(?this, ?predicate) < ?minCount)) .
        }
        UNION
        {
            FILTER (bound(?maxCount) && 
                    (spl:objectCount(?this, ?predicate) > ?maxCount)) .
        }
        UNION
        {
            FILTER bound(?valueType) .
            ?this ?predicate ?value .
            FILTER (!spl:instanceOf(?value, ?valueType)) .
        }
    }

Applied to the arguments from the example above, the query can be read as:

    ASK
    WHERE {
        {
            FILTER (bound(1) && 
                    (spl:objectCount(?this, ex:color) < 1)) .
        }
        UNION
        {
            FILTER (bound(1) && 
                    (spl:objectCount(?this, ex:color) > 1)) .
        }
        UNION
        {
            FILTER bound(ex:Color) .
            ?this ex:color ?value .
            FILTER (!spl:instanceOf(?value, ex:Color)) .
        }
    }

Based on this simple substitution mechanism, SPIN-aware tools can verify that any instance of ex:Wine has at least one and at most one value for the property ex:color. The template's body query does the cardinality checking, and also checks that the value type of all ex:color values must match the class ex:Color. Finally, the template also bundles in a spl:defaultValue that allows SPIN engines to initialize new instances of the class ex:Wine with ex:Red as default value for the ex:color property.

Hand-coding all these common design patterns directly in SPARQL would have been inconvenient and unnecessarily verbose. The example shows how SPIN can be used to define new modeling constructs or even languages with directly executable semantics based on SPARQL.

1.2 Design Considerations

The SPL is self-contained in so far that it does not rely on any other SPIN libraries or special built-in functions of a particular SPARQL engine. This means that any function or template that refers to resources from other namespaces than rdf, rdfs or owl is outside of the boundaries of SPL.

In addition to specific functions and templates, SPL also suggests a categorization scheme for functions. Abstract top-level classes such as spl:BooleanFunctions can be used to group together functions with comparable functionality.

SPL also includes definitions of the standard SPARQL functions such as bound to formally declare their arguments and provide a description. Details about those functions are not covered by this document.

SPL is designed using open source principles, and participation of the community is encouraged. Please contact the authors if you would like to add or change functionality.

 

2 Functions

The following SPL functions are stable at this stage.

spl:hasValue

spl:hasValue can be used to verify whether a given resource has a given value for a given property. The function applies rdfs:subPropertyOf inferencing, i.e. values of sub-properties of the provided property will also be checked.

Examples:

    spl:hasValue(rdfs:Class, rdfs:label, "Class")   # true
    spl:hasValue(rdf:rest, rdfs:seeAlso, rdf:)      # true

spl:hasValueOfType

spl:hasValueOfType tests whether a given subject has at least one value of a given type for a given property. The function automatically applies sub-property inferencing, i.e. also values of sub-properties of the given property will be considered. This function is comparable to owl:someValueFrom restrictions in OWL, but with closed-world semantics.

Examples:

    spl:hasValueOfType(rdfs:Class, rdfs:label, xsd:string)   # true
    spl:hasValueOfType(rdf:Class, rdfs:label, xsd:int)       # false

spl:instanceOf

spl:instanceOf can be used to verify whether a given value has a given type. The value can either be a resource or a literal. If the value is a resource, then it must have the provided type (or a subclass thereof) as one of its rdf:types. If the value is a literal, then its datatype must match the provided XSD type.

Examples:

    spl:instanceOf(owl:versionInfo, rdf:Property)   # true
    spl:instanceOf(owl:Thing, rdf:Property)         # false
    spl:instanceOf(42, xsd:integer)                 # true
    spl:instanceOf("42", xsd:integer)               # false

spl:objectCount

spl:objectCount is a convenience function that delivers the number of values of a given subject/predicate combination. This is frequently needed for constraint checking to verify the cardinality of a property.

Examples:

    spl:objectCount(owl:Thing, rdfs:label)   # 1

 

3 Templates

The following SPIN templates are defined by SPL.

spl:Argument

spl:Argument can be used to specify that instances of a class can have values for a given property. Arguments may be declared to be optional, but in general have a maximum cardinality of one. SPIN itself uses spl:Argument to define the arguments of functions and templates.

Example:

    []    a       spl:Argument ;
      rdfs:comment "the maximum number of values permitted for the property" ;
      spl:optional "true"^^xsd:boolean ;
      spl:predicate spl:maxCount ;
      spl:valueType xsd:integer .

spl:Attribute

Instances of the spl:Attribute template can be attached to classes to specify metadata about a property spl:predicate. The following kinds of metadata are supported (all of which are optional):

Example:

    :Parent
      a       rdfs:Class ;
      rdfs:label "Parent"^^xsd:string ;
      rdfs:subClassOf :Person ;
      spin:constraint
              [ a       spl:Attribute ;
                rdfs:comment "the children of this Parent"^^xsd:string ;
                spl:predicate :child ;
                spl:minCount 1 ;
                spl:valueType :Person
              ] .

spl:ConstructDefaultValues

spl:ConstructDefaultValues can be attached as a spin:constructor to root classes so that all instances of that class (and its subclasses) are initialized with default values based on the spl:defaultValue of spl:Attribute constraints.

Example:

    spin:Modules
      a       rdfs:Class ;
      rdfs:comment "An \"artificial\" parent class for all Functions and Templates." ;
      rdfs:label "Modules"^^xsd:string ;
      rdfs:subClassOf rdfs:Resource ;
      spin:constructor
              [ a       spl:ConstructDefaultValues
              ] .

spl:InferDefaultValue

spl:InferDefaultValue can be attached as a spin:rule to a class so that all instances of that class (and its subclasses) will have a default value for a certain property. In this case, default value means that the specified value will be inferred whenever there is no other value present for the subject/predicate combination. For example, if an instance of Product has no value for its madeIn property, then a default value will be inferred the next time inferences are run. Some tools may also look for such declarations to collect hints to drive user interfaces etc.

Example:

    ex:Product
      a       owl:Class ;
      rdfs:subClassOf owl:Thing ;
      spin:rule
              [ a       spl:InferDefaultValue ;
                spl:defaultValue ex:China ;
                spl:predicate ex:madeIn
              ] .

 

Appendix: Reference

The URL of the SPL schema is http://spinrdf.org/spl