Copyright © 2004 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply.
Representing part-whole relations is a very common issue for those
developing ontologies for the Semantic Web. OWL does not provide any
special
primitives for part-whole relations, but contains sufficient expressive
power
to capture most, but not all, of the common cases. The study of
part-whole
relations is an entire field in itself - "mereology" - this note is
intended
only to deal with straightforward cases for defining classes involving
part-whole relations.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document will be a part of a larger document that will provide an introduction and overview of all ontology design patterns produced by the Semantic Web Best Practices and Deployment Working Group.
This document is a W3C Working Draft and is expected to change. The SWBPD WG does not expect this document to become a Recommendation. Rather, after further development, review and refinement, it will be published and maintained as a WG Note.
This document is a Public Working Draft. We encourage public comments. Please send comments to public-swbp-wg@w3.org
Open issues, todo items:Publication as a draft does not imply endorsement by the W3C Membership. This document is a draft and may be updated, replaced or made obsolete by other documents at any time. It is inappropriate to cite this document as other than work in progress.
Many applications require representation of part-whole relations - catalogues of parts, fault diagnosis, anatomy, geography, etc. The study of part-whole relations is a large field in its own right - "mereology" and "mereotopology" and has been the topic of many papers, e.g. [Winston; Winston and Odel; Artale; Chris Welty Refs].
Although OWL contains no special constructs for dealing with part-whole relations, it does support sufficient machinery to express most key constructs for part-whole relations. Where it does not, there are a number of "work-arounds" that suffice in most situations. This note will provide basic schemas for expressing part-whole relations in OWL.
In many applications, what is needed is not a list of all parts but
rather
a list of the next level breakdown of parts, the "direct parts" of a
given
entity. It is therfore often useful to use the attribute hierarchy to
define
a subproperty of
is_part_of that is not
transitive and
links each subpart just to the next level. For these examples we shall
call
this suproperty is_part_of_directly.
is_part_of
, say has_part
. For any two
individuals, if anA
and aB
, then if
"a
nA
is_part_ofaB"
then "aB
has_part anA"
. However, care must be taken when using inverses
in
restrictions on classes. To say that "All As are parts of some B" does
not
imply that "All Bs are part of some A", i.e. the restrictionTherefore, if we want to say both that "all As are parts of Bs" and "all Bs have part some A", we have to assert each statement separately. Such pairs of statements are sometimes called "reciprocals".
Unfortunately, all current OWL reasoners scale very badly for large
part
-whole hierarchies connected by both has_part and is_part_of. Therefore,
if
reasoners are to be used, it is usually necessary to choose to use
either
is_part_of
or has_part
andbut not both..
Almost
always it is preferable to use
is_part_of because the most common queries and class definitions
are
for the parts of things, e.g. the class of all parts of a car.
Parts and wholes are ubiquitous in many applications:
A parts inventory for the devices made in a factory in which we want to be able to find the "explosion" of parts required.
is_part_of
with an
inverse has_part
(Choose your own naming conventions to
suite). is_part_of_directly
with an inverse has_part_directly
There should now be sufficient information to make basic inferences about parts, e.g. to define a class of all parts of the car, car door, etc.
Consider a simple catalogue of Vehicle parts, all subsumed by the class Item
Cars have parts Motor, Headlight, Wheel
Motors have parts Cyllinder, Carburetor
Headlights have parts head_light_bulb, reflector
A fragment of the N3 for the above example would then be:
is_part_of
a owl:TransitiveProperty , owl:ObjectProperty ;
rdfs:domain Item ;
rdfs:range Item ;
owl:inverseOf has_part .
is_part_of_directly
a owl:ObjectProperty ;
rdfs:subPropertyOf is_part_of ;
owl:inverseOf has_part_directly .
Car
a owl:Class ;
rdfs:subClassOf Item
Motor
a owl:Class ;
rdfs:subClassOf Item ;
rdfs:subClassOf
[ a owl:Restriction ;
owl:onProperty is_part_of_directly ;
owl:someValuesFrom Car
] .
Cyllinder
a owl:Class ;
rdfs:subClassOf Item ;
rdfs:subClassOf
[ a owl:Restriction ;
owl:onProperty is_part_of_directly ;
owl:someValuesFrom Motor
] .
Cyllinder_head
a owl:Class ;
rdfs:subClassOf Item ;
rdfs:subClassOf
[ a owl:Restriction ;
owl:onProperty is_part_of_directly ;
owl:someValuesFrom Cyllinder
] .
...
etc.
From the above we can define the classes: Part_of_car and
Part_of_car_directly as asubclass of Item. Informally:
Part_of_car = Item AND is_part_of someValuesFrom(Car)
Part_of_car_directly
=Item AND is_part_of someValuesFrom(Car)
,
In N3:
Part_of_car_directly
a owl:Class ;
owl:equivalentClass
[ a owl:Restriction ;
owl:onProperty is_part_of_directly ;
owl:someValuesFrom Car
] .
Part_of_car
a owl:Class ;
owl:equivalentClass
[ a owl:Restriction ;
owl:onProperty is_part_of ;
owl:someValuesFrom Car
] .
The classifier will then infer that
Part_of_car_directly subsumes
Motor
Headlight
Wheel
and that Part_of_car
subsumes
MotorThis simple list may not be what we want, in which case it is necessary systematically to define a class for the parts of each part, e.g.
Cyllinder
Cyllinder_head
Headlight
Headlight_bulb
Wheel
Tire
Part_of_motorIf all are defined in this way we get a hierarchy from the classifier:
a owl:Class ;
owl:equivalentClass
[ a owl:Restriction ;
owl:onProperty is_part_of ;
owl:someValuesFrom Motor
] .
Part_of_car
Motor
Part_of_motor
Cyllinder
Part_of_cyllinder
Cyllinder_head
...
subclassOf()
generate
hierarchies, it is important not to confuse the part-whole hierarchy
with the
subclassOf()
hierarchy. This is easily done because in
many
library and related applications, part-whole and subclass relations are
deliberately conflated into a single "broader than / narrower than"
axis. For
examplek consider the following
Vehicle
Car
Wheel
Tire
Pneumatic tire
"Automobile" is a kind of "Vehicle", but "Wheel" is a part of an "Automobile", "Tire" is a part of a "Wheel", but "Pneumatic tire" is a kind of "Tire". Such hierarchies serve well for navigation. However, they are not in general true. Statements about "all vehicles" do not necessarily, or even probably, hold for "all tires".
However, such hierarchies do need to be recreated in situations that
obey
the rule "A fault of the part is a kind of fault of the whole". For
example
you can call out the emergency service to assist with a fault in your
car if
you puncture a pneumatic tire. The following hierarchy is a correct
subclassOf()
or "kind of" hierarchy of a type that we need
to
reproduce often in OWL
Fault in CarThe easy way to say that what we really mean when we talk about a "fault in a car" is a "fault in a car or any of its parts" [1]: If we use the property has_locus to locate the fault in a particular part of the car, then:
Fault in Wheel
Fault in Tire
Fault in Pneumatic tire
This may look tedious, but
can
actually be achieved quite simply with scripting tools or the ability
to
"clone and edit" classes easily.
Part_of_car_reflexive = Car OR is_part_of someValuesFrom(Car)
In N3:
Part_of_car_reflexive
a owl:Class ;
owl:equivalentClass
[ a owl:Class ;
owl:unionOf (Car [ a owl:Restriction ;
owl:onProperty is_part_of ;
owl:someValuesFrom Car
])
] .
Part_of_car_reflexive
will be inferred to subsume
everything
subsumed by Part_of_car
plus the class Car
itself.
If reflexive parts are defined, then they can be used in the definition of faults, e.g.
Fault_in_car = Fault AND has_locus someValuesFrom(Part_of_car_reflexive)
In N3:
Fault_in_car
a owl:Class ;
owl:equivalentClass
[ a owl:Class ;
owl:intersectionOf (Fault [ a owl:Restriction ;
owl:onProperty has_locus ;
owl:someValuesFrom Part_of_car_reflexive
]) ].
A number of other relations follow the same pattern as faults, e.g. "Repairs on a part are kinds of repairs on the whole". However, not all relations follow this pattern, e.g. "Purchase of a part is not purchase of the whole"
The classic study of parts and wholes, mereology, has three
axioms:
the part-of relation is
Furthermore, in mereology, since everything is a part of itself, we have to define "proper parts" as "parts not equal to the whole". Whereas in OWL we have to do the reverse: i.e. define "parts" (analogous to "proper parts") and then define "reflexive parts" in terms of "parts".
There are a number of relations easily confused with part-whole relations. Interested readers should consult [Flavours of part of]. However, a brief list includes:
is_part_of
and has_part
In some contexts it is "more universal" to use is_part_of,
in
others to use has_part.
For example, all cars have
wheels, but
not all wheels are parts of cars. On the other hand, all leaves are
parts of
plants (at least at some time), but not all plants have leaves. The
inability
of existing classifiers to cope with ontologies mixing
is_part_of
and has_part
is a significant
limitation. In the usual case where is_part_of
is used,
the best
option may then be not to enter a saying that "all wheels are parts of
cars"
but rather to define notions of as "Wheel of a car".
Wheel_of_car
a owl:Class ;
owl:equivalentClass
[a owl:Class ;
owl:intersectionOf (Wheel [a owl:Restriction ;
owl:onProperty is_part_of ;
owl:someValuesFrom Car ])
]).
By defintion, all Wheel_of_car
s are parts of cars,
and any
Wheel
that is a part of a car is a Wheel_of_car.
This is a work around, and not ideal, but at least all statements in
the
ontology are logically true.
is_part_of,
but the various flavours of part-whole
relation are
beyond the scope of this note. See [Flavours
of part of]