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

The following data graph

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ex: <http://example.org/> .

ex:l1 rdf:first ex:l2 .
ex:l1 rdf:rest ex:l1 .
ex:l1 rdf:rest ex:l2 .

currently validates against

@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ex: <http://example.org/> .

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 Thursday, 18 February 2016 22:33:34 UTC