39 
 
 
 
 
Our current description of CheesyPizza says that if something is a CheesyPizza it is necessarily a 
Pizza and it is necessary for it to have at least one topping that is a kind of CheeseTopping.  Now 
consider some random individual. Suppose that we know that this individual is a member of the class 
Pizza. We also know that this individual has at least one kind of CheeseTopping. However, given our 
current description of CheesyPizza this knowledge is not sufficient to determine that the individual is a 
member of the class CheesyPizza. To make this possible we need to change the conditions for 
CheesyPizza from necessary conditions to necessary AND sufficient conditions. This means that not 
only are the conditions necessary for membership of the class CheesyPizza, they are also sufficient to 
determine that any random individual that satisfies them must be a member of the class CheesyPizza. 
A class (such as all the classes we have defined so far) that only has necessary conditions is called a 
primitive class. A class that has necessary and sufficient conditions is known as a defined class. In order 
to convert necessary conditions to necessary and sufficient conditions, the conditions must be moved 
from under the SubClass Of header in the class description view to be under the Equivalent To header. 
This can be done with the menu option: Edit>Convert to defined class.  
Exercise 21: Convert CheesyPizza from a Primitive Class to a Defined Class 
_____________________________________________________________________________________ 
1. Make sure CheesyPizza is selected. 
2. Select the menu option:  Edit>Convert to defined class. 
3. Synchronize the reasoner.  
_____________________________________________________________________________________ 
Your screen should now look similar to figure 4.21. Note that when a class is a defined class it is shown 
in the UI with three horizontal stripes in the circle next to its name.  
So far we have seen the reasoner do simple things such as propagate disjoint axioms from super classes 
down to subclasses. However, the reasoner is capable of doing much more. Now that we have a defined 
class we can see an example of this. Notice that there are two tabs in the Class hierarchy view. The one 
shown in figure 4.21 is the asserted hierarchy. This is the hierarchy as defined by user declared axioms. 
The other tab is the Class hierarchy (inferred) tab. This is the hierarchy as inferred by the reasoner. Up 
until we created a defined class the two tabs would be identical because we had only primitive classes in 
the ontology. Now that we have a defined class the inferred hierarchy will look different. Select the Class 
hierarchy (inferred) tab. Make sure that the reasoner is synchronized (it should say Reasoner active as in 
figure 4.21). Also, make sure to expand the CheesyPizza class in this tab. You should see a screen 
similar to figure 4.22. As you should see in the inferred tab the reasoner has inferred that all the Pizza 
classes with a cheese topping are subclasses of CheesyPizza.  
Note that if you just type a few characters, the number of possible completions may be large 
resulting in an unwieldy menu.  Also, Protégé doesn’t do things like type checking on possible 
completions.  For example, if you type “Chee” and do <control><space> you will be prompted 
with CheeseTopping and CheesyPizza as possible completions even though a Pizza is not 
in the range of hasTopping.  This is where the reasoner can also help. If you enter a class that 
is not in the range of hasTopping the reasoner will signal an inconsistency.