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

subclass inferencing #108

Closed
rapw3k opened this issue Feb 10, 2021 · 7 comments
Closed

subclass inferencing #108

rapw3k opened this issue Feb 10, 2021 · 7 comments

Comments

@rapw3k
Copy link

rapw3k commented Feb 10, 2021

Hi,
I am not very familiar yet with SHACL, so, I am trying to figure out if is possible, and if so, how, to define a shape constraint saying that the range of a property should be of type X AND any of its subclasses (rdf:subclassof*). FOr example, in shape below, how to say that the range of geo:hasGeometry is geo:Geometry and its subclasses ?
thanks

https://astrea.linkeddata.es/shapes#3f6891594ac2d163a004bec00f8db48a
a sh:PropertyShape ;
sh:class geo:Geometry ;
sh:nodeKind sh:IRIOrLiteral ;
sh:path geo:hasGeometry .

@JohannesLipp
Copy link

Dear Raul,

great to see that we can get in touch here as well. In our projects, we appended parts of the ontology to the data graphs to inform the shacl validator about these additional properties.

Example (before):

  • Ontology: geo:SubGeometry rdf:subClassOf geo:Geometry
  • Shape graph: [...] sh:path geo:hasGeometry; sh:class geo:Geometry
  • Data graph: my:InstanceA [...] geo:SubGeometry
  • Result: Constraint validation

Example (after, adding the ontology content to the data graph):

  • Ontology: geo:SubGeometry rdf:subClassOf geo:Geometry
  • Shape graph: [...] sh:path geo:hasGeometry; sh:class geo:Geometry
  • Data graph: my:InstanceA [...] geo:SubGeometry . geo:SubGeometry rdf:subClassOf geo:Geometry
  • Result: No validation anymore

Hope this helps!

@rapw3k
Copy link
Author

rapw3k commented Feb 10, 2021

Thank you @JohannesLipp !
Yes, that works.
However, this is not really practical. It would be much better that the validator would support at least class inferencing.
Perhaps this would be some feature/extension for the future ?
cu!

@HolgerKnublauch
Copy link
Collaborator

The validator (and the standard) does support subclass inferencing, based on rdfs:subClassOf triples found in the data graph. Without such triples there is no way for it to know that SubGeometry is a subclass of Geometry. Is your issue that you find adding those subClassOf triples impractical because they are only in the Ontology? What we do all the time is to use owl:imports, e.g.

ex:DataGraph owl:imports ex:Ontology

and then build a MultiUnion Graph in jena with all these graphs merged into a single virtual graph. This also means you can have

ex:ShapesGraph owl:imports ex:Ontology

which makes it easier to "attach" constraints to the classes.

@rapw3k
Copy link
Author

rapw3k commented Feb 15, 2021

Thanks @HolgerKnublauch; however that does not look so straightforward to me as you say. Perhaps I am missing something though.

In our case the data graph is encoded as a jsonld that points to the context derived from target ontology, see partial example below :

{
    "@graph" : [ {
      "@id" : "http://www.w3id.org/afarcloud/pCoord?lat=45.75&long=4.85",
      "@type" : "Point",
      "asWKT" : "POINT(45.75 4.85)"
    }, 
    {
      "@id" : "http://www.w3id.org/afarcloud/poi?lat=45.75&long=4.85",
      "@type" : "Feature",
      "hasGeometry" : "http://www.w3id.org/afarcloud/pCoord?lat=45.75&long=4.85"
    }, {
      "@id" : "urn:afc:AS09:cropsManagement:TEC:soil:sen0022",
      "@type" : [ "SoilSensor", "AfarcloudSensors" ]
    }, {
      "@id" : "urn:afc:AS09:sen0022:obs-1514810172",
      "@type" : "Observation",
      "hasFeatureOfInterest" : "http://www.w3id.org/afarcloud/poi?lat=45.75&long=4.85",
      "hasResult" : "urn:afc:AS09:sen0022:obs-1514810172/q1",
      "madeBySensor" : "urn:afc:AS09:cropsManagement:TEC:soil:sen0022",
      "observedProperty" : "http://www.w3id.org/afarcloud/soil_temperature",
      "resultTime" : "2018-01-01T12:36:12Z"
    }, {
      "@id" : "urn:afc:AS09:sen0022:obs-1514810172/q1",
      "@type" : "QuantityValue",
      "identifier" : "q1",
      "numericValue" : "0.27121272683143616",
      "unit" : "http://qudt.org/vocab/unit/DEG_C"
    } ],
    "@context" : [ "https://w3id.org/demeter/agri-context.jsonld", {
      "qudt-unit" : "http://qudt.org/vocab/unit/"
    } ]
  }

Our SHACL is:
https://raw.githubusercontent.com/rapw3k/DEMETER/master/models/SHACL/demeterAgriProfile-SHACL.ttl

The error validating the input with the SHACL is:

[ a            sh:ValidationReport ;
  sh:conforms  false ;
  sh:result    [ a                             sh:ValidationResult ;
                 sh:focusNode                  <http://www.w3id.org/afarcloud/poi?lat=45.75&amp;long=4.85> ;
                 sh:resultMessage              "ClassConstraint[<http://www.opengis.net/ont/geosparql#Geometry>]: Expected class :<http://www.opengis.net/ont/geosparql#Geometry> for <http://www.w3id.org/afarcloud/pCoord?lat=45.75&amp;long=4.85>" ;
                 sh:resultPath                 geo:hasGeometry ;
                 sh:resultSeverity             sh:Violation ;
                 sh:sourceConstraintComponent  sh:ClassConstraintComponent ;
                 sh:sourceShape                <https://astrea.linkeddata.es/shapes#3f6891594ac2d163a004bec00f8db48a> ;
                 sh:value                      <http://www.w3id.org/afarcloud/pCoord?lat=45.75&amp;long=4.85>
               ]
] .

I tried the following:
1.--- import in the SHACL the target ontology. Result: no change

@base <https://w3id.org/demeter/shacl> .
<https://w3id.org/demeter/shacl>
	rdf:type owl:Ontology ;
	owl:imports <https://w3id.org/demeter/crossDomain> .

2.--- I tried adding directly the statement in SHACL. Result: no change

sf:Point rdfs:subClassOf geo:Geometry .    

3.--- I tried adding import statement in data graph, although not sure this is correct as we use context already. Result: no change

"http://www.w3.org/2002/07/owl#imports":[
         {
            "@id":"https://w3id.org/demeter/crossDomain"
         }
      ]

4.--- I tried adding directly the statement in data graph. Result: it works. However as I said this is impractical.

{
    "@id": "http://www.opengis.net/ont/sf#Point",
    "http://www.w3.org/2000/01/rdf-schema#subClassOf": {"@id":"http://www.opengis.net/ont/geosparql#Geometry"}
  }

Any idea, or something I am missing?

@HolgerKnublauch
Copy link
Collaborator

How do you invoke this? Just adding owl:imports statements by itself doesn't do anything unless the calling code also follows those graphs and knows where to find them.

I am not fluent in JSON-LD and it's too easy to get different triples than we believe. Could you cast this to Turtle so that we can be sure we are talking about the same data, namespaces etc?

@rapw3k
Copy link
Author

rapw3k commented Feb 15, 2021

In order to do the validation, I am using https://jena.apache.org/documentation/shacl/ . I also tried using the shacl playground tool https://shacl.org/playground/

Sure, the data graph in ttl would be:

@prefix ns0: <http://www.opengis.net/ont/geosparql#> .
@prefix dc: <http://purl.org/dc/terms/> .
@prefix ns1: <http://qudt.org/schema/qudt/> .
@prefix sosa: <http://www.w3.org/ns/sosa/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl:   <http://www.w3.org/2002/07/owl#> .

<http://www.w3id.org/afarcloud/pCoord?lat=45.75&amp;long=4.85>
  ns0:asWKT "POINT(45.75 4.85)"^^ns0:wktLiteral ;
  a <http://www.opengis.net/ont/sf#Point> .

<http://www.w3id.org/afarcloud/poi?lat=45.75&amp;long=4.85>
  ns0:hasGeometry <http://www.w3id.org/afarcloud/pCoord?lat=45.75&amp;long=4.85> ;
  a ns0:Feature .

<urn:afc:AS09:cropsManagement:TEC:soil:sen0022> a <https://json-ld.org/playground/AfarcloudSensors>, <https://json-ld.org/playground/SoilSensor> .
<urn:afc:AS09:sen0022:obs-1514810172/q1>
  dc:identifier "q1" ;
  ns1:numericValue "0.27121272683143616" ;
  ns1:unit <http://qudt.org/vocab/unit/DEG_C> ;
  a ns1:QuantityValue .

<urn:afc:AS09:sen0022:obs-1514810172>
  a sosa:Observation ;
  sosa:hasFeatureOfInterest <http://www.w3id.org/afarcloud/poi?lat=45.75&amp;long=4.85> ;
  sosa:hasResult <urn:afc:AS09:sen0022:obs-1514810172/q1> ;
  sosa:madeBySensor <urn:afc:AS09:cropsManagement:TEC:soil:sen0022> ;
  sosa:observedProperty <http://www.w3id.org/afarcloud/soil_temperature> ;
  sosa:resultTime "2018-01-01T12:36:12Z"^^xsd:dateTime .

I tried adding the import like this:

@base <https://w3id.org/demeter/example> .
<https://w3id.org/demeter/example>
	owl:imports <https://w3id.org/demeter/crossDomain> .

@HolgerKnublauch
Copy link
Collaborator

Sorry but this repo here is about the TopBraid SHACL API, not the one from Jena. I suggest asking the jena-users mailing list.

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