I am building a smart home ontology. I now have a class hierarchy like that:
I
Hatim's answer may work for you, but I think it might be better not to use equivalent class axioms when you don't have to, and to avoid tying Mild Status to particular temperatures and humidities. After all, what it means for a Room to have a mild status is very different for what it means for a Sauna to have a mild status.
I'd recommend using a General Class Axiom to say that:
If a Room has a temperature and a humidity within the specified ranges, then the Room has a mild status.
As a class axiom, that's:
Room and (hasTemperature some integer[≥18,≤22]) and (hasHumidity some integer[≥40,≤50]) subClassOf (hasStatus value Mild_Status)
That's almost exactly what you can write in Protege:
Here's the ontology (in RDF/XML and in TTL) with that axiom:
@prefix : <https://stackoverflow.com/q/29228328/1281433/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
: a owl:Ontology .
:Room a owl:Class .
:Status a owl:Class .
:Mild_Status a owl:NamedIndividual , :Status .
:hasStatus a owl:ObjectProperty .
:hasTemperature a owl:DatatypeProperty .
:hasHumidity a owl:DatatypeProperty .
[ a owl:Class ;
rdfs:subClassOf [ a owl:Restriction ;
owl:hasValue :Mild_Status ;
owl:onProperty :hasStatus
] ;
owl:intersectionOf ( :Room _:b2 _:b3 )
] .
_:b3 a owl:Restriction ;
owl:onProperty :hasTemperature ;
owl:someValuesFrom [ a rdfs:Datatype ;
owl:onDatatype xsd:integer ;
owl:withRestrictions ( _:b0 _:b4 )
] .
_:b0 xsd:minInclusive 18 .
_:b4 xsd:maxInclusive 22 .
_:b2 a owl:Restriction ;
owl:onProperty :hasHumidity ;
owl:someValuesFrom [ a rdfs:Datatype ;
owl:onDatatype xsd:integer ;
owl:withRestrictions ( _:b5 _:b1 )
] .
_:b1 xsd:minInclusive 40 .
_:b5 xsd:maxInclusive 50 .
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns="https://stackoverflow.com/q/29228328/1281433/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<owl:Ontology rdf:about="https://stackoverflow.com/q/29228328/1281433/"/>
<owl:Class rdf:about="https://stackoverflow.com/q/29228328/1281433/Room"/>
<owl:Class rdf:about="https://stackoverflow.com/q/29228328/1281433/Status"/>
<owl:Class>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty>
<owl:ObjectProperty rdf:about="https://stackoverflow.com/q/29228328/1281433/hasStatus"/>
</owl:onProperty>
<owl:hasValue>
<owl:NamedIndividual rdf:about="https://stackoverflow.com/q/29228328/1281433/Mild_Status">
<rdf:type rdf:resource="https://stackoverflow.com/q/29228328/1281433/Status"/>
</owl:NamedIndividual>
</owl:hasValue>
</owl:Restriction>
</rdfs:subClassOf>
<owl:intersectionOf rdf:parseType="Collection">
<owl:Class rdf:about="https://stackoverflow.com/q/29228328/1281433/Room"/>
<owl:Restriction>
<owl:onProperty>
<owl:DatatypeProperty rdf:about="https://stackoverflow.com/q/29228328/1281433/hasHumidity"/>
</owl:onProperty>
<owl:someValuesFrom>
<rdfs:Datatype>
<owl:onDatatype rdf:resource="http://www.w3.org/2001/XMLSchema#integer"/>
<owl:withRestrictions rdf:parseType="Collection">
<rdf:Description>
<xsd:maxInclusive rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
>50</xsd:maxInclusive>
</rdf:Description>
<rdf:Description>
<xsd:minInclusive rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
>40</xsd:minInclusive>
</rdf:Description>
</owl:withRestrictions>
</rdfs:Datatype>
</owl:someValuesFrom>
</owl:Restriction>
<owl:Restriction>
<owl:onProperty>
<owl:DatatypeProperty rdf:about="https://stackoverflow.com/q/29228328/1281433/hasTemperature"/>
</owl:onProperty>
<owl:someValuesFrom>
<rdfs:Datatype>
<owl:onDatatype rdf:resource="http://www.w3.org/2001/XMLSchema#integer"/>
<owl:withRestrictions rdf:parseType="Collection">
<rdf:Description>
<xsd:minInclusive rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
>18</xsd:minInclusive>
</rdf:Description>
<rdf:Description>
<xsd:maxInclusive rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
>22</xsd:maxInclusive>
</rdf:Description>
</owl:withRestrictions>
</rdfs:Datatype>
</owl:someValuesFrom>
</owl:Restriction>
</owl:intersectionOf>
</owl:Class>
</rdf:RDF>
You can do it with class expression editor of Protege, but there is some steps to follow :
You create the #Mild_status and make it subClassof #RoomStatus (you did it as I can see in your editor)
You have to define the domain and the range of your two data properties (#centigrade and #humidity), for example having as domain the Class #RoomStatus and as range the xml datatype integer. All this can be done with Protege.
Finally, using the class expression editor: you have to assert that #Mild_status is equivalent to:
RoomStatus
and (centigrade some integer[> 18])
and (centigrade some integer[< 22])
and (humidity some integer[> 40])
and (humidity some integer[<50])
If you want to use this expression for instance retrieval reasoning: you have to be aware that not all the reasoners support data ranges reasoning. Pellet support this kind of expression but I think that Fact++ do not.