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

Not sure if it helps, but attached is a simplified graphical workflow 
for how this proposal would work.

Holger


On 6/5/2015 9:29, Holger Knublauch wrote:
> On 6/5/2015 8:54, Peter F. Patel-Schneider wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> 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 <http://example.org/Person>" ;
>  sh:sparqlShape
>    """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 
> ex:Person".
>
> 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:
>
> sh:ShapeScope
>     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.
>
> Holger
>
>
>>
>> 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
>>>
>>>
>> -----BEGIN PGP SIGNATURE-----
>> 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
>> -----END PGP SIGNATURE-----
>

Received on Friday, 5 June 2015 00:56:57 UTC