W3C home > Mailing lists > Public > public-data-shapes-wg@w3.org > April 2016

Re: implementation of core SHACL (using proposed syntax)

From: Peter F. Patel-Schneider <pfpschneider@gmail.com>
Date: Wed, 13 Apr 2016 13:00:36 -0700
To: Holger Knublauch <holger@topquadrant.com>, public-data-shapes-wg@w3.org
Message-ID: <570EA564.8070003@gmail.com>
On 04/12/2016 10:40 PM, Holger Knublauch wrote:
> On 13/04/2016 1:11, Peter F. Patel-Schneider wrote:
[...]

> Do you have an example of a user-defined constraint component by any chance?
> How would someone formalize the kind of SPARQL generation without pre-binding?

[...]

> Holger

I have a template-driven version of SHACL.  It currently does not handle
nested validation reports, however.

It does not use pre-binding, instead using textual substitution, which is only
needed for IRIs and literals so the problems with substituting blank nodes do
not arise.


Here are a few templates for core components, including RDFS ranges and shapes
that determine whether the component is syntactically correct.

sh:datatypeIn a rdf:Property ; a sh:Shape ; rdfs:domain sh:Shape ; rdfs:range
rdf:List ;
  sh:list [ a sh:Shape ; sh:nodeKind sh:IRI ] .
shmm:datatypeInShape a sh:Shape ; sh:scopeClass sh:Shape ;
  sh:propValues ( sh:datatypeIn sh:datatypeIn ) .

sh:datatypeIn a sh:ComponentTemplate ;
  sh:templateMessage "Does not have any required datatype [l(argument)]"@en ;
  sh:message "Datatypes need to be IRIs"@en ;
  sh:templatePattern """BIND ( datatype(?this) AS ?dt )
    FILTER NOT EXISTS { VALUES ?dt { [l(argument)] } }""" .

sh:maxExclusive a rdf:Property ; a sh:Shape ; rdfs:domain sh:Shape ;
rdfs:range rdfs:Literal ;
  sh:nodeKind sh:Literal .
shmm:maxExclusiveShape a sh:Shape ; sh:scopeClass sh:Shape ;
  sh:propValues ( sh:maxExclusive sh:maxExclusive ) .

sh:maxExclusive a sh:ComponentTemplate ;
  sh:templateMessage "Too big, must be less than [argument]"@en ;
  sh:message "Minimum must be a literal"@en ;
  sh:templateFilter "( COALESCE(?this < [argument],false) )" .

sh:disjoint a rdf:Property ; a sh:Shape ; rdfs:domain sh:Shape ; rdfs:range
rdf:List ;
  sh:list shmm:pathShape ;
  sh:propValues ((rdf:rest rdf:rest) [ a sh:Shape ; sh:hasValue rdf:nil ] ) .
shmm:disjointShape a sh:Shape ; sh:scopeClass sh:Shape ;
  sh:propValues ( sh:disjoint sh:disjoint ) .

sh:disjoint a sh:ComponentTemplate ;
  sh:propValues (rdf:first [ a sh:Shape ; sh:argumentName "path1" ] ) ;
  sh:propValues ((rdf:rest rdf:first) [ a sh:Shape ; sh:argumentName "path2"]);
  sh:templateMessage "Path values not disjoint"@en ;
  sh:message "Not list of two paths"@en ;
  sh:templatePattern """?this [p(path1)] ?value1 . ?this [p(path2)] ?value1 .""" .

sh:and a rdf:Property ; a sh:Shape ; rdfs:domain sh:Shape ; rdfs:range rdf:List ;
  sh:list [ a sh:Shape ; sh:class sh:Shape ] .
shmm:andShape a sh:Shape ; sh:scopeClass sh:Shape ;
  sh:propValues ( sh:and sh:and ) .

sh:and a sh:ComponentTemplate ;
  sh:templateMessage "AND"@en ;
  sh:message "sh:and takes a list of shapes"@en ;
  sh:templateQuery """SELECT [projection] ?this ?message ?severity ?subject
?property ?object
WHERE { { [l(s(argument) " } UNION { ")] } }""" .
Received on Wednesday, 13 April 2016 20:01:05 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 19:30:31 UTC