Developing the Gender-Oriented Ontology
So far, you've seen how to develop a simple type hierarchy of clothing items. But the clothing store also needs to support browsing the inventory in a gender-oriented manner. You could repeat the process of defining new classesbut how can you assign an instance to be a member of multiple classes? The answer is to create gender-oriented classes that can infer the membership of instances from a logical analysis of their properties. There are several steps required to accomplish this, which I will illustrate by showing how you can infer membership in the WomensJeans class by adding a wornBy
property to clothing items.
For example, consider the list of clothing items extended with the wornBy
property shown in Table 2:
Table 2. Here's an extended set of clothing items showing the "worn by" property that supports gender-specific classes.
||Men and Women
By introducing classes for men's and women's clothing (MensJeans, WomensShoes, etc.) that infer their membership from the wornBy
property of individual instances, the unit tests shown in Listing 1
To implement this behavior you must create a new class named Gender, which will have two instances, male and female. This is shown below and should be familiar to you after the last section.
Next, you will need to define the wornBy
property to relate clothing items to male and female gender instances.
Notice that because this property relates instances to one another it is an object property instead of a datatype property. Now the gender-oriented classes that infer membership from the wornBy
property need to be created. The restrictions that clothing instances have one and only one each of the pricedBy
properties are referred to as necessary conditions for clothing items. That is, you are guaranteed that all clothing instances will have these properties, but not that all instances that meet these conditions must be clothing instances.
But in order to be able to infer the class of an instance from its properties, the class must define conditions that are both necessary and sufficient to infer class membership. For example, it is sufficient to infer that an instance is a member of the WomensClothing class if that instance is an instance of the Clothing class and meets the condition that its wornBy
property points to the female gender instance. The following code defines just this set of conditions for women's clothing.
section is used to indicate that two classes have precisely the same membership. In this case the WomensClothing class contains all the instances of the anonymous set of instances having the wornBy
property with a female gender instance as a target that are also instances of clothing.
You can easily follow a similar pattern to create the other gender-clothing classes and pass the remainder of the test cases.
By now I hope you have seen how an ontological representation of the clothing catalog simplifies the expression of a multi-parented hierarchy. There are other advantages to this approach including extensibility and consistency checking, but these are beyond the scope of this article and I refer you to the related resources section for more information. But although you might appreciate the expressiveness of OWL you, like many, might also balk at its verbosity.
|Figure 7. Editing the Sample Ontology in Protégé: Here's how the sample clothing ontology looks when viewed in the Protégé ontology editor.|
Fortunately, you don't have to hand-roll these documents, because there are several ontology editors availablesee this comprehensive survey of ontology editor tools
. The most popular ontology editor is
from Stanford University. Protégé is a comprehensive ontology editor framework with many available plug-ins that help with a wide variety of tasks, including visualization, querying, and integration with inferencing engines. In fact, Figure 2
and Figure 3
were produced using the OWLViz plugin. Figure 7
shows a screenshot of the clothing catalog ontology opened in Protégé.
Lastly I would like to point out that you can build ontologies that reference your operational data sources and vice versa. Earlier in this article you created an identifiedBy
property that assigned a unique product ID to each article of clothing sold in the store. You could use an identifier such as this to relate an instance in an ontology to an entity in an operational data store. Because many things change constantly, such as the number of in-stock clothing items, it would not be a good idea to store that type of information in an ontology. An ontology is well suited for capturing the relationships between concepts in a domain, but relational databases excel at dealing with large amounts of constantly changing data.
The sample storefront application does just this with an in-memory representation of available inventory. If you run the application and click the "Buy Now" link five times, the application subsequently displays that item as sold. That's because each time you click the link the application decrements the available inventory count in its memory-based operational data source.
But you can also relate your operational data sources back to your ontology through Uniform Resource Indicators (URIs). Because every resource in an OWL ontology is identified by a unique URI you can store the URIs in your operational data sources in such a way that applications consuming its data can easily reference corresponding ontologies to retrieve additional information and perform additional queries.