-
Notifications
You must be signed in to change notification settings - Fork 44
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
rdfs:subPropertyOf as hierarchy in widget #704
Comments
Well, it works already this way. See https://blog.sparna.fr/2025/01/21/sparnatural-shacl-configuration-manual-automated-off-the-shelf/ and in particular https://blog.sparna.fr/wp-content/uploads/2025/01/sparnatural-hierarchy.gif. |
Ah, my bad! Thanks! In this example, where would the rdfs:subPropertyOf be specified? Its not in https://www.nakala.fr/sparnatural/nakala-shacl-filtered.ttl nor in https://www.nakala.fr/sparnatural/nakala-statistics.ttl, right? It might feature in the separate OWL file, but I assume it could also be in the SHACL (if shapes are classes), right?
|
It is in the DublinCore ontology (dcterms_2012-06-14.n3). The DublinCore ontology is passed along with the SHACL specs to Sparnatural: (from https://www.nakala.fr/sparnatural/) <spar-natural
src="nakala-shacl-filtered.ttl nakala-statistics.ttl edm.owl.rdf ore-terms.rdf dcterms_2012-06-14.n3 nakala-labels.ttl"
endpoint="https://nakala.fr/sparql" lang="fr" defaultLang="fr" distinct="true" limit="1000"
debug="true"></spar-natural> (see how multiple files are given in the src attribute) Nothing prevents you from putting the rdfs:subPropertyOf in the SHACL. But they better fit in a separate OWL file;
That's a little more elaborated. What you need is a statistics file like this one: https://shacl-play.sparna.fr/play/generate#statistics-model |
Wonderful! I'll try to implement all of this and get back to you, if stuck ;) |
SHACL: g17sn:apostolic_dispensation a rdfs:Class,
sh:NodeShape ;
rdfs:label "apostolic dispensation"@en ;
volipi:iconName "fa-solid fa-gavel" ;
sh:name "apostolic dispensation" ;
sh:nodeKind sh:IRI ;
sh:order 2.0 ;
sh:targetClass grace:apostolic_dispensation .
g17sn:apostolic_provision a rdfs:Class,
sh:NodeShape ;
rdfs:label "apostolic provision"@en ;
volipi:iconName "fa-solid fa-gavel" ;
sh:name "apostolic provision" ;
sh:nodeKind sh:IRI ;
sh:order 2.0 ;
sh:targetClass grace:apostolic_provision . OWL grace:apostolic_provision a owl:Class ;
rdfs:label "apostolic provision"@en ;
rdfs:subClassOf grace:papal_grace .
grace:apostolic_dispensation a owl:Class ;
rdfs:label "apostolic dispensation"@en ;
rdfs:subClassOf grace:papal_grace . I put both configs to load into Sparnatural, but won't work like that. If I stick to something like |
I suspect this can come from the fact that your NodeShape are also types with rdfs:Class. Either:
|
Correct, that's the cause! |
I used Otherwise I get a mix that is not well formed (see SELECT DISTINCT ?event_1 ?event_1_label WHERE {
?event_1 rdf:type <https://g17.dhi-roma.it/shacl/sparnatural-config/event>;
<https://g17.dhi-roma.it/ontology/called> ?event_1_label;
((<https://g17.dhi-roma.it/ontology/object_object>*)|^(<https://g17.dhi-roma.it/ontology/event_object>*)) ?object_2.
?object_2 rdf:type <https://g17.dhi-roma.it/ontology/object>.
} |
For properties, it doesn't work like it does for classes with hierarchies in SHACL: g17sn:biography_event a rdfs:Property,
sh:PropertyShape ;
rdfs:label "biography event"@en ;
volipi:message "Tooltip for biography event" ;
dash:searchWidget sparnatural:ListProperty ;
rdfs:subPropertyOf g17sn:participates_in ;
sh:class grace:biographical_event ;
sh:name "experienced" ;
sh:node g17sn:biographical_event ;
sh:nodeKind sh:IRI ;
sh:order 2.0 ;
sh:path grace:biography_event .
g17sn:participates_in a rdfs:Property,
sh:PropertyShape ;
rdfs:label "participates in"@en ;
volipi:message "Tooltip for participates in" ;
dash:searchWidget sparnatural:ListProperty ;
rdfs:subPropertyOf g17sn:event_object ;
sh:class grace:event ;
sh:name "participates in" ;
sh:node g17sn:event ;
sh:nodeKind sh:IRI ;
sh:order 1.0 ;
sh:path grace:participates_in . This will not make the widget show a hierarchical property select. |
No no no, you need to have this: g17sn:biography_event a rdfs:Property,
sh:PropertyShape ;
rdfs:label "biography event"@en ;
volipi:message "Tooltip for biography event" ;
dash:searchWidget sparnatural:ListProperty ;
sh:class grace:biographical_event ;
sh:name "experienced" ;
sh:node g17sn:biographical_event ;
sh:nodeKind sh:IRI ;
sh:order 2.0 ;
sh:path grace:biography_event .
g17sn:participates_in a rdfs:Property,
sh:PropertyShape ;
rdfs:label "participates in"@en ;
volipi:message "Tooltip for participates in" ;
dash:searchWidget sparnatural:ListProperty ;
sh:class grace:event ;
sh:name "participates in" ;
sh:node g17sn:event ;
sh:nodeKind sh:IRI ;
sh:order 1.0 ;
sh:path grace:participates_in .
# HERE :
grace:participates_in rdfs:subPropertyOf grace:biography_event .
The subpropertyOf is between the properties themselves not between the shapes. Besides, here too you shouldn't use rdfs:Property as a type of your shapes (remove triples |
Thanks! I wrote the SHACL analogue to the (working) SHACL definitions for classes: g17sn:locality a rdfs:Class,
sh:NodeShape ;
rdfs:label "locality"@en ;
volipi:iconName "fa-solid fa-map-marker-alt" ;
volipi:message "A term for a specific area or neighborhood within a larger geographic or administrative region, often used in ecclesiastical contexts to specify church jurisdictions." ;
rdfs:subClassOf g17sn:place ;
sh:description "A term for a specific area or neighborhood within a larger geographic or administrative region, often used in ecclesiastical contexts to specify church jurisdictions." ;
sh:name "locality" ;
sh:nodeKind sh:IRI ;
sh:order 2.0 ;
sh:targetClass grace:locality .
g17sn:place a rdfs:Class,
sh:NodeShape ;
rdfs:label "place"@en ;
volipi:iconName "fa-solid fa-map-marker-alt" ;
volipi:message "Tooltip for place" ;
rdfs:subClassOf g17sn:anything ;
sh:name "place" ;
sh:nodeKind sh:IRI ;
sh:order 21.0 ;
sh:property g17sn:contains,
g17sn:falls_within,
g17sn:has_main_type,
g17sn:is_primary_place_of,
g17sn:place_name,
g17sn:wkt ;
sh:targetClass grace:place . that's why I said it behaves differently. Maybe the above is poorly done for SHACL, but it works with Sparnatural (widget shows hierarchy, no seperate OWL needed) |
But it works if I split OWL and SHACL I don't want to have them in two files, but could simply parse them in one: https://dataria.org/static/sparnatural/config.ttl |
@tfrancart sorry to reopen, but I fail to set more than one nested subProperty. Here a snippet: g17sn:related_to_place_78 a sh:PropertyShape ;
rdfs:label "related to place"@en ;
volipi:message "what happened at this place" ;
sh:class grace:place,
g17raw:description ;
sh:description "what happened at this place" ;
sh:name "related to place" ;
sh:nodeKind sh:IRI ;
sh:or ( [ sh:class g17sn:place_54 ;
sh:node g17sn:place_54 ] [ sh:class g17sn:description_171 ;
sh:node g17sn:description_171 ] ) ;
sh:order 1.0 ;
sh:path grace:related_to_place .
grace:related_to_place a owl:ObjectProperty ;
rdfs:label "related to place"@en ;
rdfs:comment "what happened at this place" ;
rdfs:domain [ a owl:Class ;
owl:unionOf ( grace:event grace:object ) ] ;
rdfs:range [ a owl:Class ;
owl:unionOf ( grace:place g17raw:description ) ] ;
rdfs:subPropertyOf grace:place_object .
g17sn:place_object_1180 a sh:PropertyShape ;
rdfs:label "place object"@en ;
volipi:message "Tooltip for place object" ;
sh:class grace:place ;
sh:name "place object" ;
sh:node g17sn:place_54 ;
sh:nodeKind sh:IRI ;
sh:path grace:place_object .
grace:place_object a owl:ObjectProperty ;
rdfs:label "place object"@en ;
rdfs:domain grace:anything ;
rdfs:range grace:place ;
rdfs:subPropertyOf grace:refers_to .
g17sn:refers_to_173 a sh:PropertyShape ;
rdfs:label "refers to"@en ;
volipi:message "A wildcard property to find any direct entity relation" ;
sh:class grace:anything ;
sh:description "A wildcard property to find any direct entity relation" ;
sh:name "refers to" ;
sh:node g17sn:anything_914 ;
sh:nodeKind sh:IRI ;
sh:path grace:refers_to .
grace:refers_to a owl:ObjectProperty ;
rdfs:label "refers to"@en ;
rdfs:comment "A wildcard property to find any direct entity relation" ;
rdfs:domain grace:anything ;
rdfs:range grace:anything . IssueWhy is Screenshots |
I think it's due to a conflict in the properties' domains. I could resolve it but not quite sure what is the logical reason for it.
|
@ch-sander I am bit lost. Could you share your complete not-working-as-expected config file ? so I can to reproduce |
@tfrancart sorry for the delay! src=https://dataria.org/static/sparnatural/config.ttl https://dataria.org/file/results/rdf/ontology/graceful17.ttl IssueGeneral issue is that I don't quite understand how/why ExampeSee the (from my POV identical) specs snippet to define Whether it works in this case depends on This is one example of many (all a bit different, not always due to a property path, but also relying on conforming range and domain and the respective g17sn:falls_within_954 a sh:PropertyShape ;
rdfs:label "falls within"@en ;
volipi:message "Tooltip for falls within (transitive property)" ;
dash:searchWidget sparnatural:ListProperty ;
sh:class grace:place ;
sh:name "falls within" ;
sh:node g17sn:place_54 ;
sh:nodeKind sh:IRI ;
sh:order 1.0 ;
sh:path [ sh:oneOrMorePath grace:falls_within ] .
g17sn:falls_within_calculated_1347 a sh:PropertyShape ;
rdfs:label "falls within calculated"@en ;
volipi:message "Tooltip for falls within calculated" ;
sh:class grace:place ;
sh:name "falls within calculated" ;
sh:node g17sn:place_54 ;
sh:nodeKind sh:IRI ;
sh:order 1.0 ;
sh:path grace:falls_within_calculated .
grace:falls_within a owl:ObjectProperty ;
rdfs:label "falls within"@en ;
rdfs:domain grace:place ;
rdfs:range grace:place ;
rdfs:subPropertyOf grace:place_object .
owl:inverseOf grace:contains .
grace:falls_within_calculated a owl:ObjectProperty ;
rdfs:label "falls within calculated"@en ;
rdfs:domain grace:place ;
rdfs:range grace:place ;
rdfs:subPropertyOf grace:place_object .
grace:place a owl:Class ;
rdfs:label "place"@en ;
rdfs:subClassOf [ a owl:Restriction ;
owl:cardinality "1"^^xsd:nonNegativeInteger ;
owl:onProperty grace:has_main_type ],
[ a owl:Restriction ;
owl:cardinality "1"^^xsd:nonNegativeInteger ;
owl:onProperty grace:type_of_place ],
grace:anything .
g17sn:place_54 a sh:NodeShape ;
rdfs:label "place"@en ;
volipi:iconName "fa-solid fa-map-marker-alt" ;
volipi:message "Tooltip for place" ;
sh:name "place" ;
sh:nodeKind sh:IRI ;
sh:order 21.0 ;
sh:property g17sn:address_956,
g17sn:contains_955,
g17sn:event_object_917,
g17sn:falls_within_954,
g17sn:falls_within_calculated_1347,
g17sn:falls_within_custom_1346,
g17sn:geometry_1164,
g17sn:has_main_type_1009,
g17sn:institution_object_1183,
g17sn:is_primary_place_of_1057,
g17sn:person_object_1185,
g17sn:place_literal_951,
g17sn:place_name_953,
g17sn:place_object_1180,
g17sn:related_to_place_78,
g17sn:type_object_1179,
g17sn:type_of_place_58,
g17sn:wkt_952 ;
sh:targetClass grace:place .
g17sn:place_object_1180 a sh:PropertyShape ;
rdfs:label "place object"@en ;
volipi:message "Tooltip for place object" ;
sh:class grace:place ;
sh:name "place object" ;
sh:node g17sn:place_54 ;
sh:nodeKind sh:IRI ;
sh:path grace:place_object . Screenshots
ExpectationI would have thought it works exactly like for |
Another example, that I couldn't figure out: grace:has_main_type a owl:ObjectProperty ;
rdfs:label "has main type"@en ;
rdfs:domain [ a owl:Class ;
owl:unionOf ( grace:entry grace:person grace:archive grace:source grace:event grace:type grace:place grace:institution grace:date grace:object grace:monetary_value grace:dedication grace:identifier grace:anything ) ] ;
rdfs:range grace:type ;
rdfs:subPropertyOf grace:type_object .
g17sn:has_main_type_1009 a sh:PropertyShape ;
rdfs:label "has main type"@en ;
volipi:message "Tooltip for has main type" ;
dash:searchWidget sparnatural:ListProperty ;
sh:class grace:type ;
sh:maxCount 1 ;
sh:minCount 1 ;
sh:name "has main type" ;
sh:node g17sn:type_47 ;
sh:nodeKind sh:IRI ;
sh:path grace:has_main_type . why is this property |
while the widget super nicely reflects rdfs:subClassOf as nested selector, why not also allow this for rdfs:subPropertyOf if specified in SHACL? Maybe the same horizontal design can be used in UI. For my data the hierarchy of properties is even more important than for classes.
The text was updated successfully, but these errors were encountered: