W3C home > Mailing lists > Public > public-data-shapes-wg@w3.org > April 2016

Re: implementation of core SHACL (using proposed syntax)

From: Peter F. Patel-Schneider <pfpschneider@gmail.com>
Date: Tue, 12 Apr 2016 08:11:12 -0700
To: Holger Knublauch <holger@topquadrant.com>, public-data-shapes-wg@w3.org
Message-ID: <570D1010.7040007@gmail.com>
Here are a few examples.   These were generated using a simple test harness
that  calls an internal function to generate the query for a shape in a shapes
graph, prints the query, and then runs the query against a data graph.

Dimitris should be able to provide a few examples of the SPARQL code that his
implementation produces as well.  The output may not be too different.


ex:t1 a sh:Shape ;
 sh:scopeClass ex:tscope1 ;
 sh:class ex:tclass1 .

PREFIX sh: <http://www.w3.org/ns/shacl#>
# SHAPE start <http://ex.com/t1>
  SELECT  ?this ?message ?severity
         ?subject ?predicate ?object (<http://ex.com/t1> AS ?shape )
  WHERE { # SHAPE body
  { # FRAGMENT
  SELECT  ?this ("Does not have required class ex:tclass1" AS ?message)
(<http://www.w3.org/ns/shacl#Violation> AS ?severity) (?this AS ?object)
  WHERE {  ?this rdf:type/rdfs:subClassOf* <http://ex.com/tscope1> .
          FILTER ( ! EXISTS { ?this rdf:type/rdfs:subClassOf*
<http://ex.com/tclass1> } ) } }
        } # SHAPE end <http://ex.com/t1>


ex:t9 a sh:Shape ;
 sh:scopeClass ex:tscope2 ;
 sh:equals ( ex:p1 ( ex:p2 ex:p2 ) ).

PREFIX sh: <http://www.w3.org/ns/shacl#>
# SHAPE start <http://ex.com/t9>
  SELECT  ?this ?message ?severity
         ?subject ?predicate ?object (<http://ex.com/t9> AS ?shape )
  WHERE { # SHAPE body
  { # FRAGMENT
  SELECT  ?this ("Paths don't have equal values" AS ?message)
(<http://www.w3.org/ns/shacl#Violation> AS ?severity) (?this AS ?object)
  WHERE {  ?this rdf:type/rdfs:subClassOf* <http://ex.com/tscope2> .
          { { ?this <http://ex.com/p1> ?value . MINUS { ?this
<http://ex.com/p2>/<http://ex.com/p2> ?value . } } UNION
         { ?this <http://ex.com/p2>/<http://ex.com/p2> ?value . MINUS { ?this
<http://ex.com/p1> ?value.  } } } } }
        } # SHAPE end <http://ex.com/t9>


ex:unl a sh:Shape ;
  sh:scopeClass ex:unlC ;
  sh:propValues ( ex:propunl [ a sh:Shape ; sh:hasValue ex:snli ] ) .


PREFIX sh: <http://www.w3.org/ns/shacl#>
# SHAPE start <http://ex.com/unl>
  SELECT  ?this ?message ?severity
         ?subject ?predicate ?object (<http://ex.com/unl> AS ?shape )
  WHERE { # SHAPE body
  { # newContext
  SELECT  ?this ?message ?severity ?subject ?predicate ?object
  WHERE {
   {SELECT (?childGrandparent AS ?parent) ?this # (?childParent AS ?this)
           ?message ?severity ?subject ?predicate ?object
     WHERE
     {{ SELECT (?grandparent AS ?childGrandparent) (?parent AS ?childParent)
               (?message AS ?childMessage) (?severity as ?childSeverity)
               (?subject AS ?childSubject) (?predicate AS ?childPredicate) ?object
        WHERE {     # SHAPE start "ub1bL296C30"
  SELECT ?parent ?this ?message ?severity
         ?subject ?predicate ?object ("ub1bL296C30" AS ?shape )
  WHERE { # SHAPE body
  { # hasValue
  SELECT ?parent ("Missing required value ex:snli" AS ?message)
(<http://www.w3.org/ns/shacl#Violation> AS ?severity)
  WHERE { { SELECT (IF(BOUND(?p),?p,"UNKNOWN P") AS ?parent)
(IF(BOUND(?gp),?gp,"UNKNOWN GP") AS ?grandparent)
	WHERE { { SELECT (IF(BOUND(?this),?this,"UNK T") AS ?p)
(IF(BOUND(?parent),?parent,"UNK P") AS ?gp) WHERE { ?this
rdf:type/rdfs:subClassOf* <http://ex.com/unlC> . } }
	} }
          FILTER NOT EXISTS { { ?parent <http://ex.com/propunl> ?this . }
FILTER sameTerm(?this,<http://ex.com/snli>) } } }
        } # SHAPE end "ub1bL296C30"

              } }
      BIND( (IF(BOUND(?childSubject), ?childSubject, ?childParent)) AS ?subject )
      BIND( (IF(BOUND(?childSubject), ?childPredicate, ex:propunl)) AS
?predicate )
      BIND( (IF(BOUND(?childParent), ?childParent, "UNKNOWN")) AS ?this )
      BIND( CONCAT("In path ex:propunl ",?childMessage) AS ?message )
      BIND( <http://www.w3.org/ns/shacl#Violation> AS ?severity )
      } }
      ?this rdf:type/rdfs:subClassOf* <http://ex.com/unlC> . # subshape inner
      } }
        } # SHAPE end <http://ex.com/unl>








On 04/11/2016 09:55 PM, Holger Knublauch wrote:
> Peter,
>
> in order to better understand how your algorithm works, would you be able to
> share some examples of the SPARQL that gets generated? Also, I assume you have
> some non-trivial test cases - these may be valuable resources for the WG in
> general.
>
> (Regardless of whether the WG decided to generally recommend a
> SPARQL-transformation approach, there certainly would be value in exploring
> this possibility, e.g. as a WG note or in papers).
>
> Thanks,
> Holger
>
>
> On 23/03/2016 3:22, Peter F. Patel-Schneider wrote:
>> I put together an implementation of core SHACL with my syntax proposal.  It is
>> available at https://github.com/pfps/shacl
>>
>> There is a single python 2.7 file that can be called as
>>    python shacl.py data shapes
>> to validate the data graph against the shapes graph and print the validation
>> reports.
>>
>> This implements my proposed syntax but there is also code that will handle
>> most of the differences between the two syntaxes.
>>
>> This implementation is a pure transformation to SPARQL.  A SHACL shape is
>> transformed into a SPARQL query and the solutions in the result set are the
>> violations of the shape.
>>
>> There are a few differences between this implementation and the current spec
>> besides the syntax differences.  There is no translation from the result set
>> to a graph.  The subject, predicate, and object come from where the violation
>> was detected.  Severities may be handled slightly differently.
>>
>>
>> peter
>>
>
>
Received on Tuesday, 12 April 2016 15:11:42 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 19:30:31 UTC