Hi Tim,
your example has sh:qualifiedValueShapesDisjoint true on all three
cases, but they are NOT disjoint. All that the three helper shapes
verify is that the values of rdfs:label are strings. Nothing else. The
constraint applies to all instances.
Did you probably expect that sh:node would also implicitly check for the
rdf:type? It doesn't. The fact that for example st:Streaming_Company is
both sh:NodeShape and owl:Class doesn't make a difference for
validation, it is only used for targeting of nodes.
So you would need to add constraints on rdf:type, e.g. using sh:class.
In the attached version I have removed the disjoint statements and
instead added three sh:class constraints. This is producing no violations.
Not sure if this exactly what you want to test, but maybe one step
closer. Keep in mind that deep sh:node structures may badly impact
performance and cause problems with recursion.
Maybe what you really want would be to leave the sh:class constraints in
instead of sh:node, but then when a user validates the root instance
(e.g. on a form) it should also walk into adjacent instances and check
their constraints using class membership?
Holger
On 2021-07-07 2:46 am, Tim Smith wrote:
Hi Holger,
I had not tried sh:qualifiedValueShape. After adding three
sh:property statements for the st:owns property, it worked mostly as
expected. I added a fourth property shape to ensure that st:owns has
only instances of the three classes as the object. Otherwise, once
the three qualifiedValueShapes were satisfied, I could add anything
using st:owns without a violation.
Now I've hit another wrinkle, I need the validation of
st:Entertainment_Holding_Company to be recursive, meaning that all
values upon which st:Entertainment_Holding_Company is dependent must
also be valid, even if they are two, three, or more hops away in the
graph. I.e. The graph pattern I'm defining is not just a single
instance and its nearest neighbors. Thus, it's not sufficient to say:
sh:qualifiedValueShape [
sh:class st:Streaming_Company ;
] ;
I need to be able to trigger the validation of the
st:Streaming_Company instance such that if that instance is invalid,
the st:Entertainment_Holding_Company instance is also flagged as
invalid. In other contexts, I have been able to use sh:node in place
of sh:class in order to get this recursive validation behavior.
sh:qualifiedValueShape [
sh:node st:Streaming_Company ;
] ;
However, in this case, using TBC/ME 7.02, changing one of the three
property shapes to sh:node generates violations for the other two
property shapes. Changing all three generates a violation for all
three qualified property shapes. Example below. Is this the expected
behavior? Is it possible to get recursive validation to enable
validation of "large" graph patterns? This is a key capability to
being able to evaluate SysML models for completeness and accuracy.
Example RDF file attached (with sh:node in the property shapes).
Thanks for your input,
Tim
image.png
On Fri, Jul 2, 2021 at 6:59 PM Holger Knublauch
<hol...@topquadrant.com <mailto:hol...@topquadrant.com>> wrote:
Hi Tim,
have you tried
https://www.w3.org/TR/shacl/#QualifiedValueShapeConstraintComponent
<https://www.w3.org/TR/shacl/#QualifiedValueShapeConstraintComponent>
with min count and max count 1 and sh:class? You need three
property shapes on the same property.
Holger
On 3/07/2021 7:51 am, Tim Smith wrote:
Hi,
I have a need to model this constraint in SHACL:
/*An Entertainment Holding Company must own one and only one
instance of EACH of the following classes: Movie Company, Racing
Company, and Streaming Company in order to be a valid instance of
Entertainment Holding Company.*/
This is an example of a valid instance:
image.png
Any more or less than 3 st:owns triples or more or less than 1
instance of the three classes listed above should be a violation.
I have tried numerous ways to model this behavior without
success. SHACL seems to iterate through each object of the
st:owns property where I'm making a statement about the set of
st:owns objects. I encounter this type of problem frequently so
I'm hoping there is a pattern I can apply as a generic solution.
Something like sh:and but where sh:and would look across all
objects of sh:path.
Am I missing something simple? The one solution that I know
works is the one that I cannot use - creating a new property and
property shape for each class e.g. st:ownsMovieCompany. If this
is the only solution, then I can never use a "generic" property
like "owns", "category", etc.... This will result in a property
explosion and would rapidly become unworkable in industry-sized
models.
Thanks in advance for your input,
Tim
--
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-users+unsubscr...@googlegroups.com
<mailto:topbraid-users+unsubscr...@googlegroups.com>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/topbraid-users/CAF0WbnKXEb%2BArirQXCq9w5ZH-Y7b%3DX7apZge%2BU_UxCnFVznxPw%40mail.gmail.com
<https://groups.google.com/d/msgid/topbraid-users/CAF0WbnKXEb%2BArirQXCq9w5ZH-Y7b%3DX7apZge%2BU_UxCnFVznxPw%40mail.gmail.com?utm_medium=email&utm_source=footer>.
--
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-users+unsubscr...@googlegroups.com
<mailto:topbraid-users+unsubscr...@googlegroups.com>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/topbraid-users/bd4c0653-340d-f188-bf20-95582b4656f6%40topquadrant.com
<https://groups.google.com/d/msgid/topbraid-users/bd4c0653-340d-f188-bf20-95582b4656f6%40topquadrant.com?utm_medium=email&utm_source=footer>.
--
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-users+unsubscr...@googlegroups.com
<mailto:topbraid-users+unsubscr...@googlegroups.com>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/topbraid-users/CAF0Wbn%2ByHvjQgEMmshwqNgG4Bt-Fn1_0SfTJJhDmPUSDyJQD1Q%40mail.gmail.com
<https://groups.google.com/d/msgid/topbraid-users/CAF0Wbn%2ByHvjQgEMmshwqNgG4Bt-Fn1_0SfTJJhDmPUSDyJQD1Q%40mail.gmail.com?utm_medium=email&utm_source=footer>.
--
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-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/topbraid-users/a184cce1-2620-3331-0f73-a41d02df0f0e%40topquadrant.com.
# baseURI: http://data.pg.com/data/graph/SHACL_test
# imports: http://datashapes.org/dash
# prefix: st
@prefix dash: <http://datashapes.org/dash#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix st: <http://data.pg.com/data/graph/SHACL_test#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://data.pg.com/data/graph/SHACL_test>
a owl:Ontology ;
owl:imports <http://datashapes.org/dash> ;
owl:versionInfo "Created with TopBraid Composer" ;
.
st:Company
a owl:Class ;
a sh:NodeShape ;
rdfs:label "Company" ;
rdfs:subClassOf owl:Thing ;
.
st:Company_1
a st:Company ;
rdfs:label "Company 1" ;
.
st:Entertainment_Holding_Company
a owl:Class ;
a sh:NodeShape ;
rdfs:label "Entertainment Holding Company" ;
rdfs:subClassOf st:Company ;
sh:property [
sh:path st:owns ;
sh:description "An Entertainment Holding Company must own one and only
one instance of Movie Company and Racing Company and Streaming Company." ;
sh:name "Movie Company" ;
sh:qualifiedMaxCount 1 ;
sh:qualifiedMinCount 1 ;
sh:qualifiedValueShape [
sh:node st:Movie_Company ;
] ;
] ;
sh:property [
sh:path st:owns ;
sh:description "An Entertainment Holding Company must own one and only
one instance of Movie Company and Racing Company and Streaming Company." ;
sh:name "Racing Company" ;
sh:qualifiedMaxCount 1 ;
sh:qualifiedMinCount 1 ;
sh:qualifiedValueShape [
sh:node st:Racing_Company ;
] ;
] ;
sh:property [
sh:path st:owns ;
sh:description "An Entertainment Holding Company must own one and only
one instance of Movie Company and Racing Company and Streaming Company." ;
sh:name "Streaming Company" ;
sh:qualifiedMaxCount 1 ;
sh:qualifiedMinCount 1 ;
sh:qualifiedValueShape [
sh:node st:Streaming_Company ;
] ;
] ;
sh:property [
sh:path st:owns ;
sh:or (
[
sh:class st:Racing_Company ;
]
[
sh:class st:Streaming_Company ;
]
[
sh:class st:Movie_Company ;
]
) ;
] ;
.
st:Movie_Company
a owl:Class ;
a sh:NodeShape ;
rdfs:label "Company 2" ;
rdfs:subClassOf st:Company ;
sh:class st:Movie_Company ;
sh:property [
a sh:PropertyShape ;
sh:path rdfs:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
sh:minCount 1 ;
sh:name "label" ;
] ;
.
st:Movie_Company_1
a st:Movie_Company ;
rdfs:label "Movie Company 1" ;
.
st:Movie_Racing_Streaming_LLC
a st:Entertainment_Holding_Company ;
st:owns st:Movie_Company_1 ;
st:owns st:Racing_Company_1 ;
st:owns st:Streaming_Company_1 ;
rdfs:label "Movie Racing Streaming LLC" ;
.
st:Not_a_Company
a owl:Class ;
a sh:NodeShape ;
rdfs:label "Not a Company" ;
rdfs:subClassOf owl:Thing ;
.
st:Not_a_Company_1
a st:Not_a_Company ;
rdfs:label "Not a Company 1" ;
.
st:Racing_Company
a owl:Class ;
a sh:NodeShape ;
rdfs:label "Racing Company" ;
rdfs:subClassOf st:Company ;
sh:class st:Racing_Company ;
sh:property [
a sh:PropertyShape ;
sh:path rdfs:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
sh:minCount 1 ;
sh:name "label" ;
sh:nodeKind sh:Literal ;
] ;
.
st:Racing_Company_1
a st:Racing_Company ;
rdfs:label "Racing Company 1" ;
.
st:Racing_Company_2
a st:Racing_Company ;
rdfs:label "Racing Company 2" ;
.
st:Streaming_Company
a owl:Class ;
a sh:NodeShape ;
rdfs:label "Streaming Company" ;
rdfs:subClassOf st:Company ;
sh:class st:Streaming_Company ;
sh:property [
a sh:PropertyShape ;
sh:path rdfs:label ;
sh:datatype xsd:string ;
sh:maxCount 1 ;
sh:minCount 1 ;
sh:name "label" ;
] ;
.
st:Streaming_Company_1
a st:Streaming_Company ;
rdfs:label "Streaming Company 1" ;
.
st:owns
a owl:ObjectProperty ;
rdfs:label "owes" ;
.