Patrick -

That split should work. It's because SPARQL does not allow variables in paths.

?subject  $listPredicate/rdf:rest*/rdf:first  ?object

is bad syntax and seems to line up with the error message

5.3 Validation with SPARQL-based Constraints
"""
substitute the variable PATH where it appears in the predicate position of a triple pattern
"""
and it says triple pattern which has only a variable or URI in the predicate slot not a path.

So "?s $PATH ?o" but nothing more complex.

    Andy


On 23/08/2021 22:06, Patrick Golden wrote:
My solution was to just break up the list-lookup part of the SPARQL query into two elements:

$this $listPredicate ?listHead .
?listHead rdf:rest*/rdf:first ?missing .

Easy enough!

On 8/23/21 12:11 PM, Patrick Golden wrote:
Hello,

I'm trying to write a sh:ConstraintComponent that validates whether two predicates have the same objects. One predicate has multiple objects and the other has an object with an ordered RDF list of those same nodes. In Turtle, a valid graph looks like:


@prefix ex: <http://example.org/> .

ex:Thing
     ex:p1 ex:a, ex:b, ex:c ;
     ex:p2 ( ex:a ex:b ex:c ) .


I can create a SPARQL constraint that expresses this:


:ListPredEqualityConstraint
     a sh:SPARQLConstraint ;
     sh:prefixes [
         sh:declare
         [
             sh:prefix "ex" ;
             sh:namespace "http://example.org/"^^xsd:anyURI
         ] ,
     ]
     sh:select """
SELECT $this ?missing
WHERE {

     {
       $this ex:p2/rdf:rest*/rdf:first ?missing
       MINUS
       { $this ex:p1 ?missing }
     }
     UNION
     {
       $this ex:p1 ?missing
       MINUS
       { $this ex:p2/rdf:rest*/rdf:first ?missing }
     }
}
""" .


I have multiple pairs of predicates to which this constraint can apply, so I wanted to make a generic constraint component which can take each of the two predicates as parameters. This is how I tried to model that:


:ListMatchConstraintComponent
     a sh:ConstraintComponent ;
     sh:parameter [
         sh:path ex:unorderedPredicate ;
     ] ;
     sh:parameter [
         sh:path ex:listPredicate ;
     ] ;
     sh:nodeValidator [
         a sh:SPARQLSelectValidator ;
         sh:select """
SELECT $this ?missing
WHERE {

     {
       $this $listPredicate/rdf:rest*/rdf:first ?missing
       MINUS
       { $this $unorderedPredicate ?missing }
     }
     UNION
     {
       $this $unorderedPredicate ?missing
       MINUS
       { $this $listPredicate/rdf:rest*/rdf:first ?missing }
     }
}
"""
     ] .


For each predicate pair constraint, I create a shape like this:


:P1P2ListMatchConstraint
     a sh:NodeShape ;
     :unorderedPredicate ex:p1 ;
     :listPredicate ex:p2 .


However, when I run `shacl validate` for the graph against this shape, I see the result:

$ shacl v -s shape.ttl -d graph.ttl
org.apache.jena.shacl.parser.ShaclParseException: Bad query: Encountered " "/" "/ "" at line 8, column 27.
Was expecting one of:
     <IRIref> ...
     <PNAME_NS> ...
     <PNAME_LN> ...
     <BLANK_NODE_LABEL> ...
     <VAR1> ...
     <VAR2> ...
     "true" ...
     "false" ...
     <INTEGER> ...
     <DECIMAL> ...
     <DOUBLE> ...
     <INTEGER_POSITIVE> ...
     <DECIMAL_POSITIVE> ...
     <DOUBLE_POSITIVE> ...
     <INTEGER_NEGATIVE> ...
     <DECIMAL_NEGATIVE> ...
     <DOUBLE_NEGATIVE> ...
     <STRING_LITERAL1> ...
     <STRING_LITERAL2> ...
     <STRING_LITERAL_LONG1> ...
     <STRING_LITERAL_LONG2> ...
     "(" ...
     <NIL> ...
     "[" ...
     <ANON> ...
     "<<" ...


I am guessing that the values for the parameters in the constraint ($unorderedPredicate, $listPredicate) are not allowed to be in SPARQL property paths (e.g. $this $listPredicate/rdf:rest*/rdf:first ?missing). Is that the case? Are there alternative ways to achieve what I'm trying to do?

Thank you,
Patrick

Reply via email to