- From: Peter F. Patel-Schneider <pfpschneider@gmail.com>
- Date: Thu, 9 Jun 2016 18:44:36 -0700
- To: RDF Data Shapes Working Group <public-data-shapes-wg@w3.org>
The boilerplate is SPARQL code what with $this, $context, and $predicate pre-bound and ?value not in scope produces solutions for ?value as the value nodes. It can either bind ?subject and ?object as appropriate or these can be determined by the governing code, which is the solution used here. A suitable boilerplate that does not use anything beyond pre-binding is given here, but it would also be possible to do something more sophisticated. [boilerplate] { $this $predicate ?value . FILTER ( sameTerm($context,sh:PropertyConstraint) ) } UNION { ?value $predicate $this . FILTER ( sameTerm($context,sh:InversePropertyConstraint) ) } UNION { BIND ( $this AS ?value ) FILTER ( sameTerm($context,sh:NodeConstraint) ) } The code for the core constraint components is then as follows: sh:class SELECT $this ?value WHERE { [boilerplate] FILTER NOT EXISTS { ?value rdf:type/rdfs:subClassOf* $class } } sh:classIn SELECT $this ?value WHERE { [boilerplate] FILTER NOT EXISTS { GRAPH $shapesGraph { $classIn (rdf:rest*)/rdf:first ?class . } ?value rdf:type/rdfs:subClassOf* ?class . } } sh:datatype SELECT $this ?value WHERE { [boilerplate] FILTER NOT ( isLiteral(?value) && datatype(?value) = $datatype ) } sh:datatypeIn SELECT $this ?value WHERE { [boilerplate] FILTER NOT EXISTS { GRAPH $shapesGraph { $classIn (rdf:rest*)/rdf:first ?datatype . } FILTER ( isLiteral(?value) && datatype(?value) = ?datatype ) } } sh:maxExclusive SELECT $this ?value WHERE { [boilerplate] FILTER (?value < $maxExclusive) } sh:maxInclusive is similar sh:minExclusive is similar sh:minInclusive is similar sh:in SELECT $this ?value WHERE { [boilerplate] FILTER NOT EXISTS { GRAPH $shapesGraph { $in (rdf:rest*)/rdf:first ?value . } } } sh:minLength SELECT $this ?value WHERE { [boilerplate] FILTER NOT ( !isBlank(?value) && STRLEN(STR(?value)) >= $minLength ) } sh:maxLength is similar sh:nodeKind SELECT $this ?value WHERE { [boilerplate] FILTER NOT ((isIRI(?value) && $nodeKind IN (sh:IRI, sh:BlankNodeOrIRI, sh:IRIOrLiteral) ) || (isLiteral(?value) && $nodeKind IN ( sh:Literal, sh:BlankNodeOrLiteral, sh:IRIOrLiteral)) || (isBlank(?value) && $nodeKind IN ( sh:BlankNode, sh:BlankNodeOrLiteral, sh:BlankNodeOrLiteral))) } sh:pattern SELECT $this ?value WHERE { [boilerplate] FILTER NOT (!isBlank(?value) && IF(bound($flags), regex(str(?value), $pattern, $flags), regex(str(?value), $pattern))) } sh:stem SELECT $this ?value WHERE { [boilerplate] FILTER NOT (isIRI(?value) && STRSTARTS(str(?value), $stem)) } sh:shape SELECT $this ?value ?failure WHERE { [boilerplate] BIND (sh:hasShape(?value, $shape, $shapesGraph) AS ?hasShape) . BIND (!bound(?hasShape) AS ?failure) . FILTER (?failure || !?hasShape) . } sh:hasValue SELECT $this ?value WHERE { FILTER NOT EXISTS { [boilerplate] FILTER (sameTerm(?value,$hasValue) ) } sh:maxCount SELECT SAMPLE($this) WHERE { [boilerplate] } HAVING ( COUNT ( DISTINCT ?value ) > $maxCount ) sh:minCount is similar sh:equals SELECT $this ?value WHERE { { [boilerplate] MINUS { $this $equals ?value . } } UNION { $this $equals ?value . MINUS { [boilerplate] } } } sh:disjoint SELECT $this ?value WHERE { [boilerplate] $this $disjoint ?value . } sh:lessThan SELECT $this ?value WHERE { [boilerplate] $this $lessThan ?value2 . FILTER (!(?value < ?value2)) } sh:lessThanOrEquals is similar sh:uniqueLang SELECT SAMPLE($this) ?lang WHERE { { FILTER ($uniqueLang) } [boilerplate] BIND (lang(?value) AS ?lang) FILTER (isLiteral(?value) && bound(?lang) && ?lang != "") } GROUP BY ?lang HAVING ( COUNT(?this) > 1 ) sh:qualifiedMaxCount SELECT SAMPLE($this) ( SUM(?failed)>0 AS ?failure ) WHERE { [boilerplate] BIND (sh:hasShape(?value, $qualifiedValueShape, $shapesGraph) AS ?hasShape) BIND (!bound(?hasShape) AS ?failure) BIND ( IF(?failure,1,0) AS ?failed ) FILTER ( IF(?failure, true, ?hasShape) ) } HAVING ( ( COUNT ( DISTINCT ?value ) > $qualifiedMaxCount ) || ( SUM(?failed) > 0 ) ) sh:qualifiedMinCount is similar sh:closed SELECT $this ?value WHERE { { FILTER ($closed) } [boilerplate] ?value ?predicate ?object . FILTER (NOT EXISTS { GRAPH $shapesGraph { $currentShape sh:property/sh:predicate ?predicate . } } && ( !bound($ignoredProperties) || NOT EXISTS { GRAPH $shapesGraph { $ignoredProperties rdf:rest*/rdf:first ?predicate . } } ) ) } sh:not SELECT $this ?value ?failure WHERE { [boilerplate] BIND (sh:hasShape(?value, $not, $shapesGraph) AS ?hasShape) . BIND (!bound(?hasShape) AS ?failure) . FILTER (?failure || ?hasShape) . } sh:and SELECT $this ?value ?failure WHERE { [boilerplate] GRAPH $shapesGraph { $and (rdf:rest*)/rdf:first ?conjunct . } BIND (sh:hasShape(?value, ?conjunct, $shapesGraph) AS ?hasShape) BIND (!bound(?hasShape) AS ?failure) FILTER (?failure || !?hasShape) } sh:or SELECT $this ?value WHERE { [boilerplate] FILTER NOT EXISTS { GRAPH $shapesGraph { $or (rdf:rest*)/rdf:first ?disjunct . } BIND (sh:hasShape(?value, ?disjunct, $shapesGraph) AS ?hasShape) BIND (!bound(?hasShape) AS ?failure) FILTER ( !?failure || ?hasShape ) } } peter
Received on Friday, 10 June 2016 01:45:12 UTC