Re: shapes-ACTION-35: Proposal for lists (ISSUE-99 and ISSUE-119)

This looks identical to what both Simon and I suggested independently, see

This would reopen ISSUE-119 which we previously closed by stating no 
fix. The only reason to reopen this to me would be that we might then 
have an official response to the question "how to state that the range 
of a property is rdf:List":

     a sh:Shape ;
     sh:property [
         # Values of this property must be lists of type ex:Person
         sh:predicate ex:myListProperty ;
         sh:memberShape [
             sh:constraint [
                 sh:class ex:Person ;
     ] .

In a sense we already have two alternatives to state that something is a 
list, namely using rdfs:range (or OWL) or even sh:valueShape with a 
suitable shape that walks the rdf:List structure. This may be sufficient.

I still predict people will stumble over why they cannot use sh:class 
rdf:List. Also it doesn't help tools that try to make sense of shape 
definitions. How many more special cases do we want to require here? A 
tool that tries to figure out the range of a property must look for:
- sh:datatype
- sh:datatypeIn
- sh:class
- sh:classIn
- sh:directType
- owl:allValuesFrom
- rdfs:range
- and soon "if sh:memberShape exists then infer rdf:List".

This is becoming dangerously unusable in practice, inefficient to handle 
and impossible to justify to users.

Overall this is just another instance of the tension between formal 
rigidity and practical usefulness.

Also, we have not yet talked about the other special case in the current 
draft: if sh:class is rdfs:Resource then we currently allow any blank 
node or IRI even if it has no rdf:type. How else would we specify that? 
It would require a complex sh:or between two sh:nodeKind constraints - 
very ugly. Shall we add yet another special syntax just to keep sh:class 


On 19/02/2016 8:33, Peter F. Patel-Schneider wrote:
> The following data graph
> @prefix rdf: <> .
> @prefix ex: <> .
> ex:l1 rdf:first ex:l2 .
> ex:l1 rdf:rest ex:l1 .
> ex:l1 rdf:rest ex:l2 .
> currently validates against
> @prefix sh: <> .
> @prefix rdf: <> .
> @prefix ex: <> .
> ex:s1 a sh:Shape ;
>    sh:scopeNode ex:l1 ;
>    sh:constraint [ a sh:Constraint ; sh:class rdf:List ] .
> This special cases rdf:List, but in a way that is not useful at all, as it
> validates something that should not be considered to be a list.  If lists
> are to be treated specially, SHACL should do something reasonable for them.
> A reasonable approach to supporting lists is to have a special constraint
> construct for lists whose elements validate against a shape, as in
> ex:personList a sh:Shape ;
>    sh:constraint [ a sh:Constraint ;
>      sh:list [ a sh:Shape;
>        sh:constraint [ a sh:Constraint; sh:class ex:Person ] ] ] .
> The shape here is true of a node if it is a single-tailed finite RDF list
> and each of the list elements validates against the embedded shape.  This is
> the case for a node precisely when the transitive-reflexive closure of
> rdf:next from the node contains rdf:nil and for each node in the closure it
> must be the case that either the node is rdf:nil and it has no outgoing
> rdf:next or rdf:first edges or if it is not rdf:nil then the node has
> precisely one outgoing rdf:next edge and precisely one outgoing rdf:first
> edge and the object of the outgoing rdf:first edge has SHACL type ex:Person.
> This construct can validate lists that have different kinds of conditions,
> such as lists of blank nodes
> ex:blankList a sh:Shape ;
>    sh:constraint [ a sh:Constraint ;
>      sh:list [ a sh:Shape;
>        sh:constraint [ a sh:Constraint; sh:nodeKind sh:BlankNode ] ] ] .
> or lists of childless people
> ex:childlessList a sh:Shape ;
>    sh:constraint [ a sh:Constraint ;
>      sh:list [ a sh:Shape;
>        sh:constraint [ a sh:Constraint; sh:class ex:Person ] ;
>        sh:property [ a sh:PropertyConstraint;
>          ex:predicate ex:child; ex:maxCount 0 ] ] ] .
> It can even validate lists that have no conditions on their elements, but
> just must be well-formed lists
> ex:anyList a sh:Shape ;
>    sh:constraint [ a sh:Constraint ; sh:list [ a sh:Shape ] ] .

Received on Friday, 19 February 2016 00:37:13 UTC