Is it possible to write a shape that validates domain and range of a given property? - properties

I try to validate my ontology instances using SHACL shapes. However, I cannot find how to say that a given property instance is valid only if it has an instance of Class1 as a subject and an instance of Class2 as an object.
In other words, I want to specify the domain (i.e., Class1) and the range (i.e., Class2) of this property.
In the following example, we precise that the range is (customer and person), but the domain is not specified.
ex:InvoiceShape
a sh:NodeShape ;
sh:property [
sh:path ex:customer ;
sh:class ex:Customer ;
sh:class ex:Person ;
] .
I know it is possible to specify a target class (TC) for the shape, but this limits the range of the property ex:customer when the domain is TC and not in all cases.
Is it possible to write a shape that fix domain and range of a given property?
Thank you!

To state that the property constraint above applies to all instances of ex:Invoice, you either add ex:InvoiceShape rdf:type rdfs:Class or ex:InvoiceShape sh:targetClass ex:Invoice. This however does not specify that all subjects of an ex:customer triple must be instances of ex:Invoice.
To make sure that the property ex:customer can only be used at instances of ex:Invoice, you can use:
ex:InverseInvoiceShape
a sh:NodeShape ;
sh:targetSubjectsOf ex:customer ;
sh:class ex:Invoice .
The shape above applies to all subjects of an ex:customer triple. A violation will be reported if that subject is not an instance of ex:Invoice.
FWIW your original example states that the values of ex:customer must be both ex:Customer and ex:Person instances. If you meant to express 'either customer or person' then use
ex:InvoiceShape
a sh:NodeShape ;
sh:targetClass ex:Invoice ;
sh:property [
sh:path ex:customer ;
sh:or (
[ sh:class ex:Customer ]
[ sh:class ex:Person ]
)
] .

Related

Verify rdf:Container(rdf:Seq) using shacl constraints

I am currently trying to build a constraint validation shape for an incoming object of the type rdf:Seq. The shacl shapes I have used, use the path to identify triple and then add additional constraint validations on datatype, length and count. But, with the case of rdf:Seq the predicate is a variable, it can be rdf:_1, rdf:_2,.... . How can I build an effective shape where I would not know how many elements would be present in the incoming rdf:Seq object?
Or is there a way I can check that if the predicate is of the type rdfs:ContainerMembershipProperty I can validate the datatype of the data, otherwise ignore it?
Appreciate any help. Thanks!
Let's say for a given incoming data
...
<incoming node> schema:colors _:blankNode1 .
_:blankNode1 rdf:type rdf:Seq .
_:blankNode1 rdf:_1 "Red" .
_:blankNode1 rdf:_2 "Blue" .
_:blankNode1 rdf:_3 "Yello" .
...
What could the shape be?
I was trying the following
...
sh: property [
sh:path schema:colors ;
sh:class rdf:Seq ;
sh:property [
sh:path <ideally would like a regex here> ;
# or a way to identify the path to data tripe
sh:in ("Red" "Blue" "Green" ) ;
] ;
] ;
...

RDF Data Cubes, AttributeProperty, units of measurement & QUDT

I'm doing some work with RDF Data Cubes vocabulary for publishing time-series of various data, among others sensors. The measurement of the sensor is taken at a specific time at a specific station.
Both time and station I will model as qb:DimensionProperty, the measurement itself as qb:MeasureProperty. I would also like to state what unit the measurement is in. In this particular example it is atmospheric pressure at the height of the station. My understanding from the spec is that this would be modeled as qb:AttributeProperty.
In the description of the data structure I would have something like this:
<dsd/prestas0> a qb:DataStructureDefinition ;
qb:component
[ qb:dimension <stn>; qb:order 1 ],
[ qb:dimension <time>; qb:order 2 ],
[ qb:attribute <unit>; qb:order 3 ],
[ qb:measure <prestas0>; qb:order 4 ] .
<stn> a qb:DimensionProperty ;
rdfs:label "Station°" .
<time> a qb:DimensionProperty ;
rdfs:label "Time" .
<unit> a qb:AttributeProperty ;
rdfs:label "Unit" ;
rdfs:comment "The unit of the measurement" .
<prestas0> a qb:MeasureProperty ;
rdfs:label "Measurement" ;
rdfs:range xsd:float .
# Units in use
<hPa> a qudt:Unit ;
rdfs:label "Atmospheric pressure (hPa)" ;
rdfs:comment "Atmospheric pressure on station level" ;
rdfs:subClassOf unit:Pascal .
As you can see I also created an instance of a unit, called <hPa>. In there I use rdfs:subClassOf to subclass from QUDT unit:Pascal.
Now my questions:
is my understanding of using qb:AttributeProperty for the unit correct?
Is it fine to sublass from QUDT the way I did? I am aware that I have hPa while QUDT defines Pa only so I would probably have to change the data accordingly
Can I in general simply use units from QUDT directly (in terms of their URIs) if they do not need a specific tailoring like I did in this example?

Set default value to property with SPIN

I am new to SPIN. I wonder if it makes sense to use it for the following purpose. Say I have the following class hierarchy:
ex:Vehicle
ex:Car
ex:Sedan
Some classes have the property owl:equivalenClass set to some value, for example:
ex:Vehicle
owl:equivalentClass wd:MeanOfTransportation
ex:Sedan
owl:equivalentClass wd:Sedan
In the case owl:equivalentClass is not set to a value, it should take the value of it's parent class. In the above example:
ex:Car
owl:equivalentClass wd:MeanOfTransportation
Can this be accomplished with SPIN, in my case using TopBraid?
It makes sense to use SPIN for these purposes, because SPIN inference engine is the only inference engine available in TopBraid Composer Free Edition.
In other TopBraid Composer editions, the appropiateness, as well as the result obtained, may vary depending on your inferencing configuration (Inferences > Configure Inferencing).
The rule is:
rdfs:Class spin:rule [
rdf:type sp:Construct ;
sp:text """
CONSTRUCT {
?this owl:equivalentClass ?equivalentClass .
}
WHERE {
?this rdfs:subClassOf ?superClass .
?superClass owl:equivalentClass|^owl:equivalentClass ?equivalentClass .
FILTER NOT EXISTS {
?this owl:equivalentClass|^owl:equivalentClass [] .
}
} """
] .
Please note that this SPIN rule is attached to rdfs:Class : a class that instances all these ex:Car, ex:Vehicle are.
?this is a special variable that refers to the "current" instance of this class.
It seems that the spl:InferDefaultValue SPIN template can not be used in your case, because spl:InferDefaultValue doesn't accept SPARQL variables as its spl:defaultValue argument.

OWL: Is it possible to predefine relations between an individual and a range of individuals?

Let's say we have the owl:Class Person and the owl:Class Fruit. Besides that we have the owl:ObjectProperty loves (Domain: Person, Range: Fruit). There are several instances of both classes.
Is it possible to express in OWL that one particular instance of the class Person likes all fruits except apples (instance of Fruit) without having to manually define all of the loves-relations between that person and all the other Fruit instances (except apple)?
On a more abstract level: Is it possible to define relations between an instance and a range of instances (either on a class-level or for the instance itself)?
OneOf restrictions are used for what you're describing. To exclude one instance from a class (for the first part of your question) you can intersect the fruit class and the negation of OneOf(Apple), and use it to declare your apple hater as having as type a range assertion for your love property.
The solution to your problem depends whether "apple" is an instance of "fruit" or "apple" is a subclass of "fruit". It would make more sense to say that "apple" is a class, because there are many instances of apples. But since Ignazio presented a solution where "apple" is an instance, and that his answer was accepted, I will start with assuming that "apple" is an instance. Then you can achieve what you want with:
:Fruit a owl:Class .
:apple a :Fruit .
:Person a owl:Class .
:bob a :Person .
:loves a owl:ObjectProperty .
[ a owl:Class;
owl:intersectionOf (
:Fruit
[ a owl:Class; owl:complementOf [a owl:Class; owl:oneOf (:apple)] ]
)
] rdfs:subClassOf [
a owl:Restriction;
owl:onProperty [ owl:inverseOf :loves ];
owl:hasValue :bob
] .
This is saying that everything that is a :Fruit and is not :apple is necessary loved by :bob (assuming :bob is the identifier of the person who does not like apples. Note that this is different from Ignazio's solution, which does not exactly model what the OP wants.
Now, if there is a class of apples, then the solution would be:
:Fruit a owl:Class .
:Apple rdfs:subClassOf :Fruit .
:Person a owl:Class .
:bob a :Person .
:loves a owl:ObjectProperty .
[ a owl:Class;
owl:intersectionOf (
:Fruit
[ a owl:Class; owl:complementOf :Apple ]
)
] rdfs:subClassOf [
a owl:Restriction;
owl:onProperty [ owl:inverseOf :loves ];
owl:hasValue :bob
] .

How to make property of property in Protégé?

I have a following problem to model in OWL using Protégé:
Multiple Songs could be performed in different Performances. Each Song could be arranged by different Arranger in different Performance.
I already know how to relate a Song to a Performance using object property. Now, how to map a Song-Performance pair to an Arranger? (In relational database, I would call this as a "descriptive attribute" of a many-to-many Song-Performance relationship).
I know that I could use an annotation to an object property, but I would like to be able to infer something from this property. (For example: what Song has an Arranger arranged, and in which Performance?) As far as I know, I am not able to do inference from an annotation.
It's not necessary to add properties of properties to model this scenario, although a property is an object (a uri) and therefore can include any property, not just annotation properties. rdfs:subPropertyOf is a good example. Statement reification isn't necessary either. It's a matter of creating an object that holds information about the song and performance.
Here is a model that represents an Arranger's relationship to a Song-Performance:
ex:SongPerformance a owl:Class .
ex:Arranger a owl:Class .
ex:arranged rdfs:domain ex:Arranger ;
rdfs:range ex:SongPerformance .
ex:songPerformed rdfs:domain ex:SongPerformance ;
rdfs:range ex:Arranger .
ex:performedIn rdfs:domain ex:SongPerformance ;
rdfs:range ex:Arranger .
Given this list, an example instance is:
ex:Arranger-1 ex:arranged ex:SP1 .
ex:SP1 ex:performedIn ex:Performance_1 ;
ex:songPerformed ex:Song1 .
Then you can find which songs has an arranger arranged in a given performance through the following SPARQl query:
SELECT ?arranger ?song ?performance
WHERE {
?arranger a ex:Arranger ;
ex:arranged ?sp .
?sp ex:songPerformed ?song ;
ex:performedIn ?performance .
}