I have the following example instance of the Brick.ttl
buildings ontology
@prefix : <https://example.org/ontologies/test#> .
@prefix brick: <https://brickschema.org/schema/1.1/Brick#> .
@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#> .
:CH1_Active_Power_Sensor a owl:NamedIndividual,
brick:Active_Power_Sensor ;
brick:isPointOf :CH1 .
:CH1_Chilled_Water_Entering_Temperature_Sensor a owl:NamedIndividual,
brick:Chilled_Water_Entering_Temperature_Sensor ;
brick:isPointOf :CH1 .
:CH1_Chilled_Water_Leaving_Temperature_Sensor a owl:NamedIndividual,
brick:Chilled_Water_Leaving_Temperature_Sensor ;
brick:isPointOf :CH1 .
:CH2_Active_Power_Sensor a owl:NamedIndividual,
brick:Active_Power_Sensor ;
brick:isPointOf :CH2 .
:CH2_Chilled_Water_Leaving_Temperature_Sensor a owl:NamedIndividual,
brick:Chilled_Water_Leaving_Temperature_Sensor ;
brick:isPointOf :CH2 .
:CH3_Chilled_Water_Entering_Temperature_Sensor a owl:NamedIndividual,
brick:Chilled_Water_Entering_Temperature_Sensor ;
brick:isPointOf :CH3 .
:CH3_Chilled_Water_Leaving_Temperature_Sensor a owl:NamedIndividual,
brick:Chilled_Water_Leaving_Temperature_Sensor ;
brick:isPointOf :CH3 .
:CH1 a owl:NamedIndividual, brick:Chiller ;
brick:hasPoint :CH1_Active_Power_Sensor ;
brick:hasPoint :CH1_Chilled_Water_Entering_Temperature_Sensor ;
brick:hasPoint :CH1_Chilled_Water_Leaving_Temperature_Sensor .
:CH2 a owl:NamedIndividual, brick:Chiller ;
brick:hasPoint :CH2_Active_Power_Sensor ;
brick:hasPoint :CH2_Chilled_Water_Leaving_Temperature_Sensor .
:CH3 a owl:NamedIndividual, brick:Chiller ;
brick:hasPoint :CH3_Chilled_Water_Entering_Temperature_Sensor ;
brick:hasPoint :CH3_Chilled_Water_Leaving_Temperature_Sensor .
I need to identify instances which have a set of points, i.e. all brick:Chiller which has all members from {brick:Chilled_Water_Entering_Temperature_Sensor, brick:Chilled_Water_Leaving_Temperature_Sensor} (and any others).
It's easy using SPARQL, i.e.
SELECT ?subject WHERE {
?subject brick:hasPoint ?p1 .
?p1 rdf:type/rdfs:subClassOf* brick:Chilled_Water_Entering_Temperature_Sensor .
?subject brick:hasPoint ?p2 .
?p2 rdf:type/rdfs:subClassOf* brick:Chilled_Water_Leaving_Temperature_Sensor .
}
But I have a lot of these combinations and I was hoping I could define them in such a way that it's possible to reason that :CH1 and :CH3 are a specific subtype so I can directly query for it. My attempt so far is:
:CHWETLT a owl:Class ;
owl:equivalentClass [
a owl:Restriction ;
owl:onProperty :hasPoint ;
owl:allValuesFrom [
a owl:Class ;
owl:intersectionOf (
brick:Chilled_Water_Entering_Temperature_Sensor
brick:Chilled_Water_Leaving_Temperature_Sensor
)
]
] .
I'm hoping that inference would identify that :CH1 and :CH3 belong to :CHWETLT so I can query for that directly. This doesn't seem to work though - I'm not sure where to go from now. Is this possible? If so can someone point me in the correct direction?
I'm using the brickschema
python package which is (afaik) built on rdflib
and uses reasonable
as the reasoner.
In Manchester syntax, instead of
hasPoint only ( Chilled_Water_Entering_Temperature_Sensor and Chilled_Water_Leaving_Temperature_Sensor )
you need rather
( hasPoint some Chilled_Water_Entering_Temperature_Sensor ) and ( hasPoint some Chilled_Water_Leaving_Temperature_Sensor )
Back to Turtle syntax:
:CHWETLT a owl:Class ;
owl:equivalentClass [
a owl:Class ;
owl:intersectionOf (
[ a owl:Restriction ;
owl:onProperty brick:hasPoint ;
owl:someValuesFrom brick:Chilled_Water_Entering_Temperature_Sensor
]
[ a owl:Restriction ;
owl:onProperty brick:hasPoint ;
owl:someValuesFrom brick:Chilled_Water_Leaving_Temperature_Sensor
]
)
] .
Strictly speaking, this axiom is outside OWL 2 RL. However, all you need for your inference is the left-to-right subsumption. Why OWL 2 RL? The owlrl
Python reasoner mentioned in the documentation supports only this OWL profile, I suppose.