Adding Properties
For this ontology to be useful, you have to capture more information about the clothes in the catalog than just type-of relationships. For example, it would be useful to capture the price of a product or a unique ID for each product. Using OWL you declare properties similarly to classes and then use them to restrict class membership and relate instances to other instances and datatypes. As an example, here's how you declare product
price and
ID properties in OWL:
<owl:DatatypeProperty rdf:about="#pricedBy">
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#float"/>
<rdfs:domain rdf:resource="#Clothing"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:about="#identifiedBy">
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#int"/>
<rdfs:domain rdf:resource="#Clothing"/>
</owl:DatatypeProperty>
These definitions declare the existence of two properties:
pricedBy and
identifiedBy. Both are
datatype properties because they relate instances to primitive datatypes (float and int, respectively). In contrast, as you will see when developing the gender-oriented hierarchy a little later, object properties relate instances to other instances. You can see from the preceding example that properties can have both a domain and a range. The domain of a property is the class of instances to which the property can be applied. The range of a property is the range of allowed values to which it can be assigned. In the above example the
priceBy and
identifiedBy attributes can both be applied to any clothing instance and can accept any value of type float and int respectively. You can apply these properties to object instances as shown below:
<Jeans rdf:ID="RelaxedFitStonewashedJeans">
<identifiedBy rdf:datatype=
"http://www.w3.org/2001/XMLSchema#int">6
</identifiedBy>
<pricedBy rdf:datatype=
"http://www.w3.org/2001/XMLSchema#float">40.0
</pricedBy>
</Jeans>
<Jeans rdf:ID="StretchGauchoJeans">
<pricedBy rdf:datatype=
"http://www.w3.org/2001/XMLSchema#float">45.0
</pricedBy>
<identifiedBy rdf:datatype=
"http://www.w3.org/2001/XMLSchema#int">8
</identifiedBy>
</Jeans>
You can see these relationships in
Figure 6.
 | |
| Figure 6. Datatype Properties. Datatype properties relate instances to primitive datatypes. |
As useful as it is to be able to relate individual instances to datatypes and objects it is often important to be able to reason about entire classes of instances in terms of their properties. One case in point is property restrictions. Property restrictions restrict the set of allowable properties that members of a class can have. For example, in the clothing catalog it would be nice to require that all instances of clothing available in the catalog have a price (the
pricedBy property
) and a product ID (the
identifiedBy property). You can implement this in OWL via subclassing as shown in the following code:
<owl:Class rdf:about="#Clothing">
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty>
<owl:DatatypeProperty rdf:ID="pricedBy"/>
</owl:onProperty>
<owl:cardinality rdf:datatype=
"http://www.w3.org/2001/XMLSchema#int">1
</owl:cardinality>
</owl:Restriction>
</rdfs:subClassOf>
<rdfs:subClassOf>
<owl:Restriction>
<owl:cardinality rdf:datatype=
"http://www.w3.org/2001/XMLSchema#int">1
</owl:cardinality>
<owl:onProperty>
<owl:DatatypeProperty rdf:ID="identifiedBy"/>
</owl:onProperty>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
The preceding example restricts the Clothing class by subclassing anonymous classes that represent the restriction. The first anonymous class includes the set of all instances with a single
pricedBy property and the other is the set of all instances with a single
identifiedBy property. With these restrictions in place you can reason that all instances of the clothing class have a single instance of the
pricedBy and
identifiedBy properties.
You can also subclass properties, and define characteristics for them such as symmetric, inverse, etc. For a more comprehensive treatment of properties consult the links in this article, which provide more information.