Re: [ISSUE-62] A clean proposal with sh:Scope

On 6/5/2015 8:54, Peter F. Patel-Schneider wrote:
> Hash: SHA256
> There were already separate scopes for individual-based scoping and
> class-based scoping.

Yes, my proposal is to keep sh:scopeClass and sh:nodeShape as syntactic 
sugar for the frequently needed cases that they cover.

>    Do you mean that there should now be a new kind of
> template for scopes, and new special scopes, all separate from constraints?

Yes, because scopes and shapes are very different concepts. Scopes 
produce focus nodes, while constraints validate given focus nodes.

> Constraints are already available, and can do double duty as scopes.  Why
> not use them for determining the scope of a shape particularly as you then
> actually do use them for this purpose, but as filters.  I don't see what the
> point is of adding all this extra stuff.

Because they cannot always do double duty, as we had discussed here at 
length. This is due to the way that they are implemented. A constraint 
produces violation instances, but what we need are focus nodes. In other 
words, constraints look for the counter examples, while we would need 
the opposite direction to find all nodes that actually fit.

I am surprised about your feedback, because your own proposal had 
exactly the same concept, in form of sh:sparqlScope. In your own 
example, you use it to return all instance of ex:Person:

[ rdf:type sh:Constraint ;
  sh:severity sh:fatalError ;
  sh:report "SELECT ?person" ;
  sh:sparqlScope "?person rdf:type <>" ;
    """FILTER NOT EXISTS { ?person ex:offspring ?offspring .
         FILTER NOT EXISTS { ?offspring rdf:type ex:Person . } }"""
] .

If this scope were a constraint, then it would be formulated in the 
opposite direction "report an error if this is not an instance of 

All I have done is generalize your approach to allow sparqlScope to also 
be a template, and I have moved your sh:shapeScope into sh:filterShape. 
This solves the problem with your approach, that some constraints simply 
do not bind ?this. Your work-around was to inject some magic to bind 
?this with all instances of rdfs:Resource, so but even this hack now can 
have an official solution:

     a sh:ScopeTemplate
     sh:argument [
         sh:predicate sh:shape ;   # becomes ?shape in the query
         sh:valueType sh:Shape ;
         rdfs:comment "The shape that all focus nodes must have"
     ] ;
     sh:sparql """
             SELECT ?this
             WHERE {
                 ?this a rdfs:Resource .
                 FILTER sh:hasShape(?this, ?shape)
         """ .

And we side-step the question whether ?this should by default be all 
subjects, all nodes, all instances, etc. We just define a generic 
mechanism and let the model do the rest. Anyone can add their own 
scoping template.

As a bonus we don't have to look into complex SPARQL query analysis to 
find out whether a query is binding ?this and similar unnecessary 
complexity that few users will understand.

Hope this makes sense, I can elaborate further.


> peter
> On 06/03/2015 04:16 PM, Holger Knublauch wrote:
>> I thought more about the issue of generic scopes and filters and have
>> come up with a variation of Peter's design. Assuming we define
>> - Scope: takes a graph as input and produces bindings for the focus node
>> (?this)
>> Graph -> focus nodes
>> - Constraint: that takes a focus node as input and produces (violation)
>> results:
>> focus nodes -> results
>> I think we should make Scopes an explicit concept in SHACL's RDF
>> vocabulary, similar to how shapes are defined. There would be the
>> following class hierarchy:
>> sh:Scope sh:NativeScope sh:TemplateScope
>> And native scopes can have sh:sparql (or a JS body etc). Example
>> # Applies to all subjects that have a skos:prefLabel ex:MyShape sh:scope
>> [ a sh:NativeScope ; # Optional rdf:type triple sh:sparql """ SELECT
>> DISTINCT ?this WHERE { ?this skos:prefLabel ?any } """ ] ; sh:constraint
>> [ a ex:UniqueLanguageConstraint ; ex:predicate skos:prefLabel ; ] .
>> This (common) case above could be turned into a template
>> sh:PropertyScope:
>> ex:MyShape sh:scope [ a sh:PropertyScope ; sh:predicate skos:prefLabel .
>> ] ; sh:constraint [ a ex:UniqueLanguageConstraint ; ex:predicate
>> skos:prefLabel ; ] .
>> and we could provide a small collection of frequently needed scopes,
>> e.g.
>> - all nodes in a graph - all subjects - all nodes with any rdf:type - all
>> IRI nodes from a given namespace
>> Systems that don't speak SPARQL would rely on the hard-coded IRIs from
>> the core vocabulary, such as sh:PropertyScope.
>> We could now also formally define the scope behind sh:scopeClass (and
>> sh:nodeShape):
>> sh:ClassScope a sh:TemplateScope ; sh:argument [ sh:predicate sh:class ;
>> # Becomes ?class sh:valueType rdfs:Class ; ] ; sh:sparql """ SELECT
>> ?this WHERE { ?type rdfs:subClassOf* ?class . ?this a ?type . } """ .
>> In addition to these scopes, I suggest we turn sh:scopeShape into
>> sh:filterShape, and use these filters as pre-conditions that are
>> evaluated for a given set of focus nodes. The workflow then becomes:
>> - sh:scope produces bindings for ?this - sh:filterShape filters out the
>> values of ?this that do not match the given shape - the actual
>> constraints are evaluated
>> I believe this design provides the flexibility of a generic scoping
>> mechanism (as suggested in Peter's design) without getting into the
>> complexity of having to analyze SPARQL syntax or rely on hacks with
>> rdfs:Resource, while having a user-friendly syntax. The fact that we
>> separate sh:Scope from sh:Shape means that we can enforce different,
>> explicit semantics on scopes. For example we could allow a sh:Scope to
>> encapsulate another SPARQL query that tests whether a given ?this is in
>> scope, i.e. the inverse direction of the SELECT query, to optimize
>> performance.
>> Thanks, Holger
> Version: GnuPG v2
> iQEcBAEBCAAGBQJVcNcvAAoJECjN6+QThfjzi28H/3x3+0mmUmrKvEkbxuQ4Vp4a
> 1E65QIwcZuWhmocT+nHwtPT9Bb0nCMA4D+lsCfwGCp671dhoFmrHAAERe/xDKbSL
> IJ1vRkstNA0Y+QKS29M2eKtICbO+R8z3ez6xlUNUA7yY0TfE4W1zB2nHh/wzJFyY
> VM9KHhyQV7ZA+c5hdbai163rGOcFu7Mr54LsUiF2nZ5kAlgtZnJfn45Ewfip+kIO
> a5zBlyqDY5T+GvgSEvFi1u+V0RjZPVnvApxT/oRbepLOu+EintFttH8IpB4T+HBB
> yv/kyUGNH4lxNrsYVyAEzYmMi6KIUHuQEiI2VfB4tYRwLJwA7+VsECsRcRtjR/A=
> =0+/m

Received on Thursday, 4 June 2015 23:31:20 UTC