Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inheritance of property classes through rdfs:subClassOf #144

Closed
vincentkelleher opened this issue Sep 12, 2024 · 4 comments
Closed

Inheritance of property classes through rdfs:subClassOf #144

vincentkelleher opened this issue Sep 12, 2024 · 4 comments

Comments

@vincentkelleher
Copy link

Hi 👋

We've been using your library at Gaia-X for some time now and it has been very convenient, Clownface is also awesome 👍

Our case

I've found a case that doesn't seem to be managed by the library when properties have an sh:class that is a parent of the actual property class value.

Example

To make sure I wasn't creating an issue for nothing I cloned your repository and wrote a specific test case to simulate our case:

@prefix dash: <http://datashapes.org/dash#> .
@prefix ex: <http://example.org#> .
@prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix sht: <http://www.w3.org/ns/shacl-test#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<>
  rdf:type mf:Manifest ;
  mf:entries (
      <multiInheritance3>
    ) ;
.

<multiInheritance3>
  rdf:type sht:Validate ;
  rdfs:label "Test of multi level subclasses has properties of shapes" ;
  mf:action [
      sht:dataGraph <> ;
      sht:shapesGraph <> ;
    ] ;
  mf:result [
      rdf:type sh:ValidationReport ;
      sh:conforms "true"^^xsd:boolean ;
  ] ;
.

ex:TopShape
    a sh:NodeShape ;
    sh:targetClass ex:TopClass ;
.

ex:MidClassShape
    a sh:NodeShape ;
    rdfs:subClassOf ex:TopShape ;
    sh:targetClass ex:MidClass ;
.

ex:BottomClassShape
    a sh:NodeShape ;
    rdfs:subClassOf ex:MidClass ;
    sh:targetClass ex:BottomClass ;
.

ex:MainClassShape
    a sh:NodeShape ;
    sh:targetClass ex:MainClass ;
    sh:property [
                    sh:class ex:TopClass ;
                    sh:minCount 1 ;
                    sh:nodeKind sh:IRI ;
                    sh:path ex:bottom ] ;
.

ex:bottomInstance
    a ex:BottomClass ;
.

ex:mainInstance
    a ex:MainClass ;
    ex:bottom ex:bottomInstance ;
.

Expected behavior

In this test case I'm expecting the validation report to be conformant as MainClass expects ex:bottom to be of type ex:TopClass and that ex:bottomInstance is a child of ex:TopClass.

This behavior is specified in the 2.1.3.2 Class-based Targets (sh:targetClass) chapter of the SHACL specification.

What I saw

I noticed that the validateClass(..) method calls isInstanceOf(..) with nodes coming from the $data graph.

In our case, this won't work as the rdfs:subClassOf information is available in the $shapes graph.

Maybe using the shapes graph in addition to the data graph to build a class hierarchy could be a solution to this ?

@tpluscode
Copy link
Collaborator

Hello @vincentkelleher. Thank you for using the library and you kind words (credit for clownface goes to @bergos)

Regarding inheritance, unfortunately the implementation is according to spec. This has been discussed multiple times. Also here, a mere month ago: #142. Please also refer to w3c/data-shapes#185

Since this is a recurring problem, maybe we should consider actually allowing some optional change in behavior, such as merging shapes graph with the data graph. @giacomociti

@giacomociti
Copy link
Contributor

merging shapes graph and data graph may be useful, we may add an opt-in configuration switch

@vincentkelleher
Copy link
Author

Hi @tpluscode & @giacomociti

Thank you for the very quick response with some reading material for me this morning 😄

sh:subClassOf must be in the data graph

I wasn't aware that the specification was so clear about this and after reading chapter 2.1.3.2 Class-based Targets (sh:targetClass), which I mentioned above, I noticed the highlighted sentence:

image

Note that, according to the SHACL instance definition, all the rdfs:subClassOf declarations needed to walk the class hierarchy need to exist in the data graph.

Which confirms that the sh:subClassOf needs to be in the data graph.

SHACL processors can also merge graphs

I also had a look at the chapter which states that the SHACL processor must not modify the input graphs but it can build its own custom graph for validation purposes (if my understanding is correct.

image

SHACL processors MAY store the graphs that they create, such as a graph containing validation results, and this operation MAY change existing graphs in an RDF store, but not any of the graphs that were used to construct the shapes graph or the data graph.

This would mean that implementing a shapes and data graph merging opt-in configuration switch (as @giacomociti suggested) would be possible 💡

@vincentkelleher
Copy link
Author

@giacomociti @tpluscode

Since I got your feedback, I have updated our project to load the ontology into a dataset that is then filtered to only keep rdfs:subClassOf predicates as you can see here 👉 https://gitlab.com/gaia-x/technical-committee/service-characteristics-working-group/service-characteristics/-/blob/develop/toolchain/test-shacl/src/ShaclService.ts#L26

Everything seems to work fine and your implementation is flawless 👌

Thank you for your help, I'm closing this to avoid filling your issues tab with open issues 😇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants