I would like to understand how to handle multiple paths and existential quantification in SHACL rules. Let me exemplify my problem with a sample ontology.
The ontology includes the classes "Approve", "Legal", "Result", "Man", and "Machine", all disjoint. It has two properties "has-theme" and "come-from" and the following individuals:
:a rdf:type :Approve ;
:has-theme :r1,:r2 .
:r1 rdf:type :Result ;
:come-from :m1 .
:r2 rdf:type :Result ;
:come-from :m2 .
:m1 rdf:type :Man .
:m2 rdf:type :Machine .
Therefore: the Approve action ":a" has two themes: ":r1" and ":r2". The former comes from the Man ":m1", the latter comes from the Machine ":m2".
I want to write a SHACL rule stating that "Every Approve action having among its themes at least a Result that comes from a Man is Legal".
I tried this, that do NOT classify ":a" as Legal (but it should):
:testRule rdf:type sh:NodeShape;
sh:rule [rdf:type sh:TripleRule;
sh:condition :conditionTest;
sh:subject sh:this;
sh:predicate rdf:type;
sh:object ontology:Legal
];
sh:targetClass ontology:Approve.
:conditionTest
rdf:type sh:NodeShape;
sh:property
[
#IF the theme of the Approve action is a Result come from a Man
sh:path (ontology:has-theme ontology:come-from);
sh:class ontology:Man
].
The problem is that ":a" has two themes, one coming from a Man and the other from a Machine.
Then I read on the Web about sh:oneOrMorePath and I tried the following variants within sh:property:
sh:oneOrMorePath (ontology:has-theme ontology:come-from);
sh:path ([sh:oneOrMorePath ontology:has-theme] ontology:come-from);
sh:path (ontology:has-theme [sh:oneOrMorePath ontology:come-from]);
Nothing to do, these variants don't work either.
On the other hand, if I remove the triple ":r2 :come-from :m2" or the triple ":a :has-theme :r2" it works, as there is no more in the ontology a branch leading from ":a" to a non-Man.
Could any of you be so kind to help me?
Thank you!
Livio
Your requirements states "having among its themes at least a Result that comes from a Man" which sounds like an existential constraint to me. So you cannot really use sh:class here, but you may rather want to use a qualified value constraint.
I have not tried it, but something like this may work:
:conditionTest
rdf:type sh:NodeShape ;
sh:property [
sh:path (ontology:has-theme ontology:come-from) ;
sh:qualifiedMinCount 1 ;
sh:qualifiedValueShape [
sh:class ontology:Man ;
]
] .
This should mean that at least one of the values of the path has-theme/come-from must conform to the qualified value shape, which means that it must be an instance of Man.
See https://www.w3.org/TR/shacl/#QualifiedValueShapeConstraintComponent for the specification of QVCs in SHACL.
If you can use SHACL-SPARQL and import the dash namespace, you could also simply write dash:hasValueWithClass ontology:Man, see http://datashapes.org/constraints.html#HasValueWithClassConstraintComponent