-
Notifications
You must be signed in to change notification settings - Fork 30
Description
This is a fuller illustration of this comment of Issue 311, in response to this later comment also on 311. This is a modeling exercise, but rather than discuss the "right" way to model this topic, I mean to look through strategies available to SHACL 1.0 and potentially available to Node Expressions.
This example considers effects of a single boolean-valued property on other properties, but discussion should consider that there are more complex conditions that could involve multiple properties.
A community I work with has a class for actions, which might or might not link a performer of the action. For example, this would be Alice sending an email:
ex:sendEmail-1
a ex:Action ;
ex:performer ex:Alice ;
.
We would like to represent that some actions are automated. If an action is automated, it would not have a performer.
ex:receiveEmail-1
a ex:Action ;
ex:isAutomated true ;
.
The designation of automation was initially proposed as a boolean variable, and the question later came about whether an automated action should have a performer or should be disallowed from having a performer. We have a class hierarchy rooted at ex:Action
that makes it slightly less attractive to define a subclass ex:AutomatedAction
, because of some desires in the community (e.g., considerations for programming language bindings) to avoid multi-typing.
We also have automatically generated documentation, within which this rule should "render nicely."
The validation rule to implement would be, "If ex:isAutomated
is true
(explicitly), then the maximum count of ex:performer
is 0."
The condition universal to the below examples is the constraint that there is at most one value of ex:isAutomated
on any action, and it's boolean-valued:
ex:Action
a rdfs:Class, sh:NodeShape ;
sh:targetClass ex:Action ;
sh:property [
sh:path ex:isAutomated ;
sh:datatype xsd:boolean ;
sh:maxCount 1 ;
] ;
.
Styles available to SHACL 1.0
Define a class
This implementation style eschews the boolean variable entirely.
ex:AutomatedAction
a rdfs:Class, sh:NodeShape ;
rdfs:subClassOf ex:Action ;
sh:targetClass ex:AutomatedAction ;
sh:property [
sh:path ex:performer ;
sh:maxCount 0 ;
] ;
.
If both subclass and boolean variable are in the model, they can at least be constrained to be consistent within the subclass:
ex:AutomatedAction
sh:not [
sh:property [
sh:path ex:isAutomated ;
sh:hasValue false ;
] ;
] ;
.
Disjunctive form of implication
Following "p → q ⇔ ¬p ∨ q", the consistency check across the two properties would be an sh:or
on the node shape:
ex:Action
sh:or (
[
sh:not [
sh:property [
sh:path ex:isAutomated ;
sh:hasValue true ;
] ;
] ;
]
[
sh:property [
sh:path ex:performer ;
sh:maxCount 0 ;
] ;
]
) ;
.
Without an sh:message
, my understanding is this form gets pretty verbose in a SHACL validation report where the message is generated from the reporting constraint component.
Styles available to Node Expressions (?)
Please excuse misunderstandings of the current proposals of node expression syntax. Corrections welcome. I saw sh:if
mentioned on #215 and #222 .
Conditional constraints
This is drawn from #311 .
ex:Action
sh:property [
sh:path ex:performer ;
sh:maxCount [
sh:if [
sh:property [
sh:path ex:isAutomated ;
sh:hasValue true ;
] ;
] ;
sh:then 0 ;
sh:else 1 ;
] ;
] ;
.
Targeting nodes
This is drawn from a remark as @tpluscode and @HolgerKnublauch were discussing #311 on today's WG call. The gist is that this case should be handled well enough by a node expression on sh:targetNode
.
Note: I'm shaky on this syntax. Can corrections please be ported over to #339 , which I think is the most specific Issue now for sh:targetNode
? I'm eyeing sh:SPARQLTarget
and sh:condition
from the 2017 state of SHACL-AF for syntax hints.
ex:Action-extra-shape
a sh:NodeShape ;
sh:property [
sh:path ex:performer ;
sh:maxCount 0 ;
] ;
sh:targetNode [
a sh:NodeExpression ;
sh:condition [
a sh:NodeShape ;
sh:property [
a sh:PropertyShape ;
sh:path ex:isAutomated ;
sh:hasValue true ;
] ;
] ;
] ;
.
Styles available to Rules
Entail a class
This strategy does not use a node expression, and instead uses a sh:TripleRule
from SHACL-AF---a topic for the inferencing document, IIRC, but topic-scheduling corrections are welcome.
If the subclass ex:AutomatedAction
from above is defined in the ontology and shapes graph, and it's desired for users to be relieved of needing to assign rdf:type ex:AutomatedAction
in their data, then a rule can entail ex:AutomatedAction
before validation is run to check the no-performers constraint.
ex:Action
sh:rule [
a sh:TripleRule ;
sh:subject sh:this ;
sh:predicate rdf:type ;
sh:object ex:AutomatedAction ;
sh:condition [
a sh:NodeShape ;
sh:property [
a sh:PropertyShape ;
sh:path ex:isAutomated ;
sh:hasValue true ;
] ;
] ;
] ;
.
This strategy most closely mirrors what would be available in OWL by defining ex:AutomatedAction
with an equivalence class, and running OWL inferencing before SHACL validation:
ex:AutomatedAction
a owl:Class ;
owl:equivalentClass [
a owl:Class ;
rdfs:subClassOf
ex:Action ,
[
a owl:Restriction ;
owl:onProperty ex:isAutomated ;
owl:hasValue true ;
]
;
] ;
.