Hi Scott,
I may not fully understand your scenario, but I don't think this
can be expressed in SHACL Core. The problem is not so much in the
matching pattern (with the types etc) but in the subPropertyOf
link. The last line would need to become something with
sh:qualifiedMinCount 1 but you would need a sh:path and the
sh:path cannot be computed dynamically, i.e. you cannot use a
variable that gets computed using subPropertyOf. It would only
work if you can know the sub-properties in advance, when you write
the constraint.
You have it formulated in SPARQL already, so why not stay in SHACL-SPARQL? Does your target platform only support SHACL Core?
Holger
--
You received this message because you are subscribed to the Google Groups "TopBraid Suite Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/3a55f966-d99d-4d32-875e-3e32a1f643c4n%40googlegroups.com.
On Sep 3, 2021, at 8:06 PM, Holger Knublauch <hol...@topquadrant.com> wrote:
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/cca816bc-26db-4af4-2881-4ee80ff7866e%40topquadrant.com.
Unfortunately we do not have SPARQL support for SHACL, as we use an old version of Semaphore. Maybe someday in the future.
In the meantime, what about if we drop the sub-property triple pattern and have a known set of (or single) properties? Can that be expressed in SHACL? Particularly the part about targeting multiple classes and multiple parent classes.
Ok, if the properties are known you can use a pattern such as
sh:path [ sh:alternativePath ( ex:prop1 ex:prop2 ex:prop3 ) ]
; # ex:prop1|ex:prop2|ex:prop3
The rest could roughly be
ex:Shape
a sh:NodeShape ;
sh:targetClass ex:Cls1 ;
sh:not [
sh:class ex:Cls2 ;
sh:property [
sh:path ex:parent ;
sh:qualifiedValueShape [
sh:or ( [ sh:class ex:Cls3 ] [ sh:class ex:Cls4 ]
[ sh:class ex:Cls5 ] ) ;
] ;
sh:qualifiedMinCount 1 ;
) ;
sh:path [ sh:alternativePath ( ex:prop1 ex:prop2 ex:prop3
) ] ; # ex:prop1|ex:prop2|ex:prop3
sh:minCount 1 ;
]
(above I assume your rdf:type matches can be expressed using sh:class, i.e. subclasses also count).
I am not sure if the above represents your intention, but the
mechanism that I have used was basically to match the pattern that
you have in the WHERE clause and put a sh:not around it, meaning
that a violation will be reported if the instance of Cls1 also
matches the given pattern.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/49677E3C-2B4F-488F-BB6B-90881B496020%40gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/baad61dd-3f49-84e6-09d1-8db48331c1af%40topquadrant.com.
Thanks for the help Holger, it gave me some ideas, which unfortunately haven't panned out yet. First, I take it that the parent in the third-to-last line of the example should be a square bracket. Or there's something else missing in the syntax.
The most confounding part to me is how to express the class constraints, so let me focus there with three example data sets.
This is a valid shape. The target class has both Cls1 and Cls2 and the parent class has one of Cls{3, 4, 5}:ex:target1
a ex:Cls1, ex:Cls2 ;
ex:parent ex:target2 .
ex:target2
a ex:Cls3 .
This is an invalid shape only because of the extra class definition in target1. The extra class definition in target2 is OK.ex:target1
a ex:Cls1, ex:Cls2, ex:Cls6;
ex:parent ex:target2 .
ex:target2
a ex:Cls3, Cls7 .
This case could become
ex:Shape
a sh:NodeShape ;
sh:targetClass ex:Cls1, ex:Cls2 ;
sh:not [ sh:class ex:Cls6 ] ;
to state that instances of Cls1 or Cls2 cannot also be instances
of Cls6. It does NOT state that they need to have both types 1 and
2.
This is also an invalid shape because target2 does not have a class definition in Cls{3, 4, 5}:ex:target1
a ex:Cls1, ex:Cls2;
ex:parent ex:target2 .
ex:target2
a ex:Cls7 .
This case could become
ex:Shape
a sh:NodeShape ;
sh:targetClass ex:Cls1, ex:Cls2 ;
sh:property [
sh:path ex:parent ;
sh:or (
[ sh:class ex:Cls3 ]
[ sh:class ex:Cls4 ]
[ sh:class ex:Cls5 ]
)
]
But this logic feels different from what you had in your original SPARQL query, which seemed to be more "exists" than "for-all".
Note that for general non-product related questions you may get
better breadth of input on places like StackOverflow or the
https://www.w3.org/community/shacl/ mailing list or similar
places. This is not to discourage you from asking here, but to
understand that we cannot give such requests the same amount of
attention as customer questions, so my input may be rather cursory
than in-depth.
Thanks,
Holger
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/CAJ-KvVqCG_3HZUDM-NL_PR4i%2B6c4RQfL%3DyNjR5Odco5exs%3DJMg%40mail.gmail.com.