ISSUE-139: single implementations of all core constraint components

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