Third edition of Artificial Intelligence: foundations of computational agents, Cambridge University Press, 2023 is now available (including the full text).
13.3.1 Description Logic
A Uniform Resource Identifier has some meaning because someone published that it has that meaning and because people use it with that meaning. This works, but we want more. We would like to have meanings that allow a computer to do some inference.
Modern ontology languages such as OWL are based on description logics. A description logic is used to describe classes, properties, and individuals. One of the main ideas behind a description logic is to separate
- a terminological knowledge base that describes the terminology, which should remain constant as the domain being modeled changes, and
- an assertional knowledge base that describes what is true in some domain at some point in time.
Usually, the terminological knowledge base is defined at the design time of the system and defines the ontology, and it only changes as the meaning of the vocabulary changes, which should be rare. The assertional knowledge base usually contains the knowledge that is situation-specific and is only known at run time.
It is typical to use triples to define the assertional knowledge base and a language such as OWL to define the terminological knowledge base.
OWL describes domains in terms of the following:
- Individuals are things in the world that is being described (e.g., a particular house or a particular booking may be individuals).
- Classes are sets of individuals. A class is the set of all real or potential things that would be in that class. For example, the class "House" may be the set of all things that would be classified as a house, not just those houses that exist in the domain of interest.
- Properties are used to describe individuals. A datatype property has values that are primitive data types, such as integers or strings. For example, "streetName" may be a datatype property between a street and string. An object property has values that are other individuals. For example, "nextTo" may be a property between two houses, and "onStreet" may be a property between a house and a street.
OWL comes in three variants that differ in restrictions imposed on the classes and properties. In OWL-DL and OWL-Lite, a class cannot be an individual or a property, and a property is not an individual. In OWL-Full, the categories of individuals, properties, and classes are not necessarily disjoint. OWL-Lite has some syntactic restrictions that do not affect the meaning but can make reasoning simpler.
OWL does not make the unique names assumption; two names do not necessarily denote different individuals or different classes. It also does not make the complete knowledge assumption; it does not assume that all relevant facts have been stated.
Ck are classes, Pk are properties, Ik are individuals, and n is an integer. #S is the number of elements in set S:
Class | Class Contains |
owl:Thing | all individuals |
owl:Nothing | no individuals (empty set) |
owl:ObjectIntersectionOf(C1,...,Ck) | individuals in C1∩...∩Ck |
owl:ObjectUnionOf(C1,...,Ck) | individuals in C1∪...∪Ck |
owl:ObjectComplementOf(C) | the individuals not in C |
owl:ObjectOneOf(I1,...,Ik) | I1,...,Ik |
owl:ObjectHasValue(P,I) | individuals with value I on property P, i.e., {x: x P I} |
owl:ObjectAllValuesFrom(P,C) | individuals with all values in C on property P; i.e., {x: x P y →y∈C} |
owl:ObjectSomeValuesFrom(P,C) | individuals with some values in C on property P; i.e., {x: exist y∈C such that x P y} |
owl:ObjectMinCardinality(n,P,C) | individuals x with at least n individuals of class C related to x by P, i.e., {x: #{y| xPy and y∈C} ≥ n } |
owl:ObjectMaxCardinality(n,P,C) | individuals x with at most n individuals of class C related to x by P, i.e., {x: #{y| xPy and y∈C} ≤ n } |
OWL has the following predicates with a fixed interpretation, where Ck are classes, Pk are properties, and Ik are individuals; x and y are universally quantified variables.
Statement | Meaning |
rdf:type(I,C) | I∈C |
rdfs:subClassOf(C1,C2) | C1⊆C2 |
owl:EquivalentClasses(C1,C2) | C1≡C2 |
owl:DisjointClasses(C1,C2) | C1∩C2={} |
rdfs:domain(P,C) | if xPy then x∈C |
rdfs:range(P,C) | if xPy then y∈C |
rdfs:subPropertyOf(P1,P2) | xP1y implies xP2y |
owl:EquivalentObjectProperties(P1,P2) | xP1y if and only if xP2y |
owl:DisjointObjectProperties(P1,P2) | xP1y implies not xP2y |
owl:InverseObjectProperties(P1,P2) | xP1y if and only if yP2x |
owl:SameIndividual(I1,...,In) | ∀j ∀k Ij=Ik |
owl:DifferentIndividuals(I1,...,In) | ∀j ∀k j≠k implies Ij≠Ik |
owl:FunctionalObjectProperty(P) | if xPy1 and xPy2 then y1=y2 |
owl:InverseFunctionalObjectProperty(P) | if x1Py and x2Py then x1=x2 |
owl:TransitiveObjectProperty(P) | if xPy and yPz then y=z |
owl:SymmetricObjectProperty | if xPy then yPz |
Figure 13.5 gives some primitive classes and some class constructors. This figure uses set notation to define the set of individuals in a class. Figure 13.6 gives primitive predicates of OWL. The owl: prefixes are from OWL. To use these properties and classes in an ontology, you include the appropriate URI abbreviations:
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>. @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>. @prefix owl: <http://www.w3.org/2002/07/owl#>.
In these figures, xPy is a triple. Note that this is meant to define the meaning of the predicates, rather than any syntax. The predicates can be used with different syntaxes, such as XML, Turtle, or traditional relations notation.
There is one property constructor: owl:ObjectInverseOf(P), which is the inverse property of P; that is, it is the property P-1 such that yP-1x iff xPy. Note that it is only applicable to object properties; datatype properties do not have inverses, because data types cannot be the subject of a triple.
The list of classes and statements in these figures is not complete. There are corresponding datatype classes for datatype properties, where appropriate. For example, owl:DataSomeValuesFrom and owl:EquivalentDataProperties have the same definitions as the corresponding object symbols, but are for datatype properties. There are also other constructs in OWL to define properties, comments, annotations, versioning, and importing other ontologies.
owl:MinCardinality(2 :owns :building)
is the class of all individuals who own two or more buildings. That is, it is the set {x: exist i1exist i2 x :owns i1 and x :owns i2 and i1≠i2}. This class constructor must be used in a statement, for example, to say that some individual is a member of this class or to say that this is equivalent to some other class.
We first define the functional object property numberOfUnits, with domain ResidentialBuilding and range {one,two,moreThanTwo}. In Turtle this is written
:numberOfUnits rdf:type owl:FunctionalObjectProperty; rdfs:domain :ResidentialBuilding; rdfs:range owl:OneOf(:one :two :moreThanTwo).
The functional object property ownership with domain ResidentialBuilding, and range {rental,ownerOccupied,coop} can be defined similarly.
We can define an apartment building as a Residential Building where the numberOfUnits property has the value moreThanTwo and the ownership property has the value rental. To specify this in OWL, we define the class of things that have value moreThanTwo for the property numberOfUnits, the class of things that have value rental for the property ownership, and say that Apartment Building is equivalent to the intersection of these classes. In Turtle, this is
:ApartmentBuilding owl:EquivalentClasses owl:ObjectIntersectionOf ( owl:ObjectHasValue(:numberOfUnits :moreThanTwo) owl:ObjectHasValue(:onwership :rental) :ResidentialBuilding).
This definition can be used to answer questions about apartment buildings, such as the ownership and the number of units.
Note that the previous example did not really define ownership. The system has no idea what this actually means. Hopefully, a user will know what it means. Someone who wants to adopt an ontology should ensure that they use a property and a class to mean the same thing as other users of the ontology.
A domain ontology is an ontology about a particular domain of interest. Most existing ontologies are in a narrow domain that people write for specific applications. There are some guidelines that have evolved for writing domain ontologies to enable knowledge sharing:
- If possible, use an existing ontology. This means that your knowledge base will be able to interact with others who use the same ontology.
- If an existing ontology does not exactly match your needs, import it and add to it. Do not start from scratch, because then others who want to use the best ontology will have to choose. If your ontology includes and improves the other, others who want to adopt an ontology will choose yours, because their application will be able to interact with adopters of either ontology.
- Make sure that your ontology integrates with neighboring ontologies. For example, an ontology about resorts will have to interact with ontologies about food, beaches, recreation activities, and so on. Try to make sure that it uses the same terminology for the same things.
- Try to fit in with higher-level ontologies (see below). This will make it much easier for others to integrate their knowledge with yours.
- If you must design a new ontology, consult widely with other potential users. This will make it most useful and most likely to be adopted.
- Follow naming conventions. For example, call a class by the singular name of its members. For example, call a class "Resort" not "Resorts". Resist the temptation to call it "ResortConcept" (thinking it is only the concept of a resort, not a resort; see the box). When naming classes and properties, think about how they will be used. It sounds better to say that "r1 is of type Resort" than "r1 is of type Resorts", which is better than "r1 is of type ResortConcept".
- As a last option, specify the matching between ontologies. Sometimes ontology matching has to be done when ontologies are developed independently. It is best if matching can be avoided; it makes knowledge using the ontologies much more complicated because there are multiple ways to say the same thing.
Classes and Concepts
It is tempting to call the classes concepts, because symbols represent concepts: mappings from the internal representation into the object or relations that the symbols represent.
For example, it may be tempting to call the class of unicorns "unicornConcept" because there are no unicorns, only the concept of a unicorn. However, unicorns and the concept of unicorns are very different; one is an animal and one is a subclass of knowledge. A unicorn has four legs and a horn coming out of its head. The concept of a unicorn does not have legs or horns. You would be very surprised if a unicorn appeared in a class about ontologies, but you should not be surprised if the concept of a unicorn appeared. There are no instances of unicorns, but there are many instances of the concept of a unicorn. If you mean a unicorn, you should use the term "unicorn". If you mean the concept of a unicorn, you should use "concept of a unicorn". You should not say that a unicorn concept has four legs, because instances of knowledge do not have legs; only animals (and furniture) have legs.
As another example, consider a tectonic plate, which is part of the Earth's crust. The plates are millions of years old. The concept of a plate is less than a hundred years old. Someone can have the concept of a tectonic plate in their head, but they cannot have a tectonic plate in their head. It should be very clear that a tectonic plate and the concept of a tectonic plate are very different things, with very different properties. You should not use "concept of a tectonic plate" when you mean "tectonic plate" or vice versa.
Calling objects concepts is a common error in building ontologies. Although you are free to call things by whatever name you want, it is only useful for knowledge sharing if other people adopt your ontology. They will not adopt it if it does not make sense to them.
OWL, when written in Turtle, is much easier to read than when using XML. However, OWL is at a lower level than most people will want to specify or read. It is designed to be a machine-readable specification. There are many editors that let you edit OWL representation. One example is Protégé (http://protege.stanford.edu/). An ontology editor should support the following:
- It should provide a way for people to input ontologies at the level of abstraction that makes the most sense.
- Given a concept a user wants to use, an ontology editor should facilitate finding the terminology for that concept or determining that there is no corresponding term.
- It should be straightforward for someone to determine the meaning of a term.
- It should be as easy as possible to check that the ontology is correct (i.e., matches the user's intended interpretation for the terms).
- It should create an ontology that others can use. This means that it should use a standardized language as much as possible.