TopQuadrant / shacl

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

How to Use Inference When Validating #144

Closed tobiasschweizer closed 2 years ago

tobiasschweizer commented 2 years ago

Hi there,

I have made my first steps with shaclvalidate and I have a question regarding inference.

Given the following data:

<http://www.example.com/1> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/MonetaryGrant> .
<http://www.example.com/1> <http://schema.org/fundedItem> <http://www.example.com/2> .
<http://www.example.com/2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/ResearchProject> .

And the following property shape:

_:b0 <http://www.w3.org/ns/shacl#property> _:b1 .
_:b1 <http://www.w3.org/ns/shacl#class> <http://schema.org/Thing> .
_:b1 <http://www.w3.org/ns/shacl#description> "Indicates an item funded or sponsored through a [[Grant]]." .
_:b1 <http://www.w3.org/ns/shacl#maxCount> "1"^^<xsd:integer> .
_:b1 <http://www.w3.org/ns/shacl#minCount> "1"^^<xsd:integer> .
_:b1 <http://www.w3.org/ns/shacl#name> "fundedItem" .
_:b1 <http://www.w3.org/ns/shacl#nodeKind> <http://www.w3.org/ns/shacl#IRI> .
_:b1 <http://www.w3.org/ns/shacl#path> <http://schema.org/fundedItem> .

How can I pass in the information that schema:ResearchProject is a subclass of schema:Thing so that the constraint is satisfied? Would I need to use shaclinfer for that?

When using pyshacl, I use the "extra ontology graph" (https://github.com/RDFLib/pySHACL#command-line-use) to pass in the ontology stating the subclass relation between schema:ResearchProject and schema:Thing.

Thanks a lot for any hint on that.

HolgerKnublauch commented 2 years ago

As an aside, "1"^^ looks incorrect. Should be "1"^^xsd:integer, or the full URI between the <...> or just write 1 unquoted.

We typically use owl:imports to have the data graph import the shapes graph with the rdfs:subClassOf triples. So assuming that you have schema:ResearchProject rdfs:subClassOf schema:Thing in some other graph then you'd need to owl:import that other graph. I am not sure if the command line tool would follow owl:imports, but this can be simulated programmatically by creating a Jena MultiUnion with the required subgraphs and passing that into the validation engine as data graph and also the shapes graph.

tobiasschweizer commented 2 years ago

Thanks a lot for your answer.

I actually generated this from JSON-LD using pyld: jsonld.to_rdf(data, {'format': 'application/n-quads'}). I have naively assumed that this would do the job but now I notice the difference. Thanks for pointing that out!

          {
            "sh:property": {
              "sh:class": {
                "@id": "schema:Thing"
              },
              "sh:description": "Indicates an item funded or sponsored through a [[Grant]].",
              "sh:maxCount": {
                "@type": "xsd:integer",
                "@value": 1
              },
              "sh:minCount": {
                "@type": "xsd:integer",
                "@value": 1
              },
              "sh:name": "fundedItem",
              "sh:nodeKind": {
                "@id": "sh:IRI"
              },
              "sh:path": {
                "@id": "schema:fundedItem"
              }
            }
          }

I am not sure if the command line tool would follow owl:imports, but this can be simulated programmatically by creating a Jena MultiUnion with the required subgraphs and passing that into the validation engine as data graph and also the shapes graph.

Ok, thanks for the explanation.

HolgerKnublauch commented 2 years ago

Not sure if this ticket can be closed?

tobiasschweizer commented 2 years ago

Let's close it. Thanks again for the clarifications.