TopQuadrant / shacl

SHACL API in Java based on Apache Jena
Apache License 2.0
219 stars 61 forks source link

Inconsistent behaviour nested NodeShape #114

Closed cdekok closed 3 years ago

cdekok commented 3 years ago

I think the examples below should behave the same but they do not.

@prefix sh:             <http://www.w3.org/ns/shacl#> .
@prefix rdf:            <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:           <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd:            <http://www.w3.org/2001/XMLSchema#> .
@prefix shape:          <http://example.com/resources/shape/> .
@prefix test:           <http://example.com/resources/shape/Test#> .

shape:Test
    a                    sh:NodeShape ;
    sh:closed            true ;
    sh:ignoredProperties ( rdf:type ) ;
    sh:targetClass       shape:Test ;
    sh:property          [ sh:path     test:title ;
                           sh:minCount 1 ;
                           sh:maxCount 1 ;
                           sh:datatype xsd:string ; ] ;
    sh:property          [ a           sh:NodeShape ;
                           sh:path     test:group ;                           
                           sh:closed   true ;
                           sh:property [ sh:path     test:Group-text ;
                                         sh:order    8.0 ;
                                         sh:datatype xsd:string ;
                                         sh:maxCount 1 ; ] ; ]
.

With a invalid datagraph for the nested node shape as below it would return.

Datagraph

@prefix memorix:       <http://memorix.io/ontology#> .
@prefix shape:          <http://example.com/resources/shape/> .
@prefix test:           <http://example.com/resources/shape/Test#> .

<record/1>
    a shape:Test ;
    test:title "title" ;
    test:group [
        test:Group-text "text" ;
        test:Group-invalid "text" ;
    ]
.

Report

[ rdf:type     sh:ValidationReport ;
  sh:conforms  false ;
  sh:result    [ rdf:type                      sh:ValidationResult ;
                 sh:focusNode                  <http://example.com/record/1> ;
                 sh:resultMessage              "Closed[http://example.com/resources/shape/Test#Group-text] Property = <http://example.com/resources/shape/Test#group> : Object = _:B7a9e6f5f65b0fbcb79b999abaad1e72c" ;
                 sh:resultPath                 test:group ;
                 sh:resultSeverity             sh:Violation ;
                 sh:sourceConstraintComponent  sh:ClosedConstraintComponent ;
                 sh:sourceShape                _:b0 ;
                 sh:value                      [] 
               ] ;
  sh:result    [ rdf:type                      sh:ValidationResult ;
                 sh:focusNode                  <http://example.com/record/1> ;
                 sh:resultMessage              "Closed[http://example.com/resources/shape/Test#Group-text] Property = <http://example.com/resources/shape/Test#title> : Object = \"title\"" ;
                 sh:resultPath                 test:title ;
                 sh:resultSeverity             sh:Violation ;
                 sh:sourceConstraintComponent  sh:ClosedConstraintComponent ;
                 sh:sourceShape                _:b0 ;
                 sh:value                      "title"
               ] ;
  sh:result    [ rdf:type                      sh:ValidationResult ;
                 sh:focusNode                  <http://example.com/record/1> ;
                 sh:resultMessage              "Closed[http://example.com/resources/shape/Test#Group-text] Property = rdf:type : Object = <http://example.com/resources/shape/Test>" ;
                 sh:resultPath                 rdf:type ;
                 sh:resultSeverity             sh:Violation ;
                 sh:sourceConstraintComponent  sh:ClosedConstraintComponent ;
                 sh:sourceShape                _:b0 ;
                 sh:value                      shape:Test
               ]
] .

A similar shape but with a different notation through sh:node results in this.

@prefix sh:             <http://www.w3.org/ns/shacl#> .
@prefix rdf:            <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:           <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd:            <http://www.w3.org/2001/XMLSchema#> .
@prefix shape:          <http://example.com/shape/> .
@prefix test:           <http://example.com/shape/Test#> .

shape:Test
    a                    sh:NodeShape ;
    sh:closed            true ;
    sh:ignoredProperties ( rdf:type ) ;
    sh:targetClass       shape:Test ;
    sh:property          [ sh:path     test:title ;
                           sh:minCount 1 ;
                           sh:maxCount 1 ;
                           sh:datatype xsd:string ; ] ;
    sh:property          [ sh:path test:group ;
                           sh:node shape:Test-Group ; ]
.

shape:Test-Group
    a           sh:NodeShape ;
    sh:closed   true ;
    sh:property [ sh:path     test:Group-text ;
                  sh:datatype xsd:string ;
                  sh:maxCount 1 ; ]
.

Response

[ rdf:type     sh:ValidationReport ;
  sh:conforms  false ;
  sh:result    [ rdf:type                      sh:ValidationResult ;
                 sh:focusNode                  <http://example.com/record/1> ;
                 sh:resultMessage              "Closed[http://example.com/shape/Test#title, http://example.com/shape/Test#group][http://www.w3.org/1999/02/22-rdf-syntax-ns#type] Property = <http://example.com/shape/Test#testGroup> : Object = _:B702170c781855d1e4ff5bc3499f4795b" ;
                 sh:resultPath                 test:group ;
                 sh:resultSeverity             sh:Violation ;
                 sh:sourceConstraintComponent  sh:ClosedConstraintComponent ;
                 sh:sourceShape                shape:Test ;
                 sh:value                      [] 
               ]
] .

The javascript implementation does have the same report on the first shape as the second which I believe is the expected result. With the exception that the java implementation also checks for the rdf:type which the js does not so the nested shape requires a sh:ignoredProperties ( rdf:type ) ; for the java implementation.

irenetq commented 3 years ago

sh:property [ sh:path test:group ; a sh:NodeShape ; sh:closed true ; sh:property [ sh:path test:Group-text ; sh:order 8.0 ; sh:datatype xsd:string ; sh:maxCount 1 ; ] ; ] The blank node that is a subject of a triple with sh:path predicate and test:group object is "by definition" a property shape. You say that it is a node shape.

A property shape is a shape https://www.w3.org/TR/shacl/#dfn-shape in the shapes graph https://www.w3.org/TR/shacl/#dfn-shapes-graph that is the subject https://www.w3.org/TR/shacl/#dfn-subject of a triple https://www.w3.org/TR/shacl/#dfn-rdf-triple that has sh:path as its predicate https://www.w3.org/TR/shacl/#dfn-predicate. A shape has at most one value https://www.w3.org/TR/shacl/#dfn-value for sh:path.

A node shape is a shape https://www.w3.org/TR/shacl/#dfn-shape in the shapes graph https://www.w3.org/TR/shacl/#dfn-shapes-graph that is not the subject https://www.w3.org/TR/shacl/#dfn-subject of a triple https://www.w3.org/TR/shacl/#dfn-rdf-triple with sh:path as its predicate https://www.w3.org/TR/shacl/#dfn-predicate.

sh:property can be used to specify that each value node https://www.w3.org/TR/shacl/#dfn-value-nodes has a given property shape https://www.w3.org/TR/shacl/#dfn-property-shape.

In other words, this is not a valid shape.

On May 14, 2021, at 10:50 AM, Chris de Kok @.***> wrote:

I think the examples below should behave the same but they do not.

@prefix sh: http://www.w3.org/ns/shacl# . @prefix rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns# . @prefix rdfs: http://www.w3.org/2000/01/rdf-schema# . @prefix xsd: http://www.w3.org/2001/XMLSchema# . @prefix shape: http://example.com/resources/shape/ . @prefix test: http://example.com/resources/shape/Test# .

shape:Test a sh:NodeShape ; sh:closed true ; sh:ignoredProperties ( rdf:type ) ; sh:targetClass shape:Test ; sh:property [ sh:path test:title ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:string ; ] ; sh:property [ sh:path test:group ; a sh:NodeShape ; sh:closed true ; sh:property [ sh:path test:Group-text ; sh:order 8.0 ; sh:datatype xsd:string ; sh:maxCount 1 ; ] ; ] .. With a invalid datagraph for the nested node shape as below it would return.

Datagraph

@prefix memorix: http://memorix.io/ontology# . @prefix shape: http://example.com/resources/shape/ . @prefix test: http://example.com/resources/shape/Test# .

<record/1> a shape:Test ; test:title "title" ; test:group [ test:Group-text "text" ; test:Group-invalid "text" ; ] .. Report

[ rdf:type sh:ValidationReport ; sh:conforms false ; sh:result [ rdf:type sh:ValidationResult ; sh:focusNode http://example.com/record/1 ; sh:resultMessage "Closed[http://example.com/resources/shape/Test#Group-text] Property = http://example.com/resources/shape/Test#group : Object = :B7a9e6f5f65b0fbcb79b999abaad1e72c" ; sh:resultPath test:group ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:ClosedConstraintComponent ; sh:sourceShape :b0 ; sh:value [] ] ; sh:result [ rdf:type sh:ValidationResult ; sh:focusNode http://example.com/record/1 ; sh:resultMessage "Closed[http://example.com/resources/shape/Test#Group-text] Property = http://example.com/resources/shape/Test#title : Object = \"title\"" ; sh:resultPath test:title ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:ClosedConstraintComponent ; sh:sourceShape :b0 ; sh:value "title" ] ; sh:result [ rdf:type sh:ValidationResult ; sh:focusNode http://example.com/record/1 ; sh:resultMessage "Closed[http://example.com/resources/shape/Test#Group-text] Property = rdf:type : Object = http://example.com/resources/shape/Test" ; sh:resultPath rdf:type ; sh:resultSeverity sh:Violation ; sh:sourceConstraintComponent sh:ClosedConstraintComponent ; sh:sourceShape :b0 ; sh:value shape:Test ] ] . A similar shape but with a different notation through sh:node results in this.

@prefix sh: http://www.w3.org/ns/shacl# . @prefix rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns# . @prefix rdfs: http://www.w3.org/2000/01/rdf-schema# . @prefix xsd: http://www.w3.org/2001/XMLSchema# . @prefix shape: http://example.com/shape/ . @prefix test: http://example.com/shape/Test# .

shape:Test a sh:NodeShape ; sh:closed true ; sh:ignoredProperties ( rdf:type ) ; sh:targetClass shape:Test ; sh:property [ sh:path test:title ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:string ; ] ; sh:property [ sh:path test:group ; sh:node shape:Test-Group ; ] ..

shape:Test-Group a sh:NodeShape ; sh:closed true ; sh:property [ sh:path test:Group-text ; sh:datatype xsd:string ; sh:maxCount 1 ; ] ..



Response

[ rdf:type sh:ValidationReport ;
sh:conforms false ;
sh:result [ rdf:type sh:ValidationResult ;
sh:focusNode http://example.com/record/1 <http://example.com/record/1> ;
sh:resultMessage "Closed[http://example.com/shape/Test#title, http://example.com/shape/Test#group][http://www.w3.org/1999/02/22-rdf-syntax-ns#type] Property = http://example.com/shape/Test#testGroup <http://example.com/shape/Test#testGroup> : Object = _:B702170c781855d1e4ff5bc3499f4795b" ;
sh:resultPath test:testGroup ;
sh:resultSeverity sh:Violation ;
sh:sourceConstraintComponent sh:ClosedConstraintComponent ;
sh:sourceShape shape:Test ;
sh:value []
]
] .

The javascript implementation does have the same report on the first shape as the second which I believe is the expected result.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub <https://github.com/TopQuadrant/shacl/issues/114>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAG762BM5LKQVQ2JF7FIRDDTNU2E3ANCNFSM444SDH5Q>.
cdekok commented 3 years ago

Ah yes you are correct it should not contain a path I missed that.