Back to DAML homepage

Annotated DAML+OIL+DT Ontology Markup

Feedback to www-rdf-logic, please.

DAML+OIL+DT version (revision 4.1): Frank van Harmelen, Peter F. Patel-Schneider and Ian Horrocks, editors.
DAML+OIL version (revision 3.2): Frank van Harmelen, ed.
DAML-ONT version (up to revision 2.0): Lynn Andrea Stein, Dan Connolly, and Deborah McGuinness, eds.

More recent changes indicated in darker shades of grey: Version 4, Version 3.

This is an annotated walk through an example DAML+OIL+DT Ontology. The example ontology demonstrates many of the features in DAML+OIL+DT[DAML+OIL+DT], but is not intended as a complete description of the language. For this, please refer to the reference document on DAML+OIL+DT.

Superscripted text refers to notes at the end of this document. The original example ontology is available separately.

DAML+OIL+DT builds on existing Web technologies like Extensible Markup Language[XML] and Uniform Resource Identifiers[URI]. The references and suggested reading section cites introductory materials as well as official specifications for these technologies.

Contents

Setting Up Namespaces

DAML+OIL+DT, is written in RDF[RDF], i.e., DAML+OIL+DT markup is a specific kind of RDF markup. RDF, in turn, is written in XML, using XML Namespaces[XMLNS], and URIs. If you are unfamiliar with RDF, the minimalist survival guide to XML and the minimalist survival guide to RDF below may help get you started.

Thus, our example begins with an RDF start tag including several namespace declarations:

<rdf:RDF
  xmlns:rdf ="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
  xmlns:xsd ="http://www.w3.org/2000/10/XMLSchema#"
  xmlns:daml="http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt#"
  xmlns:dex ="http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt-ex#"
  xmlns:exd ="http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt-ex-dt#"
  xmlns     ="http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt-ex#"
>

So in this document, the rdf: prefix should be understood as referring to things drawn from the namespace called http://www.w3.org/1999/02/22-rdf-syntax-ns#. This is a conventional RDF declaration appearing verbatim at the beginning of almost every rdf document.xmlns:rdf

The second and third declarations make similar statements about the RDF Schema and XML Schema datatype namespaces.

The fourth declaration says that in this document, elements prefixed with daml: should be understood as referring to things drawn from the namespace called http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt# . This again is a conventional DAML+OIL+DT declaration.

The fifth declaration says that in this document, elements prefixed with dex: should be understood as referring to things drawn from the namespace called http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt-ex#, i.e., the location of this document itself.

The sixth declaration says that in this document, elements prefixed with exd: should be understood as referring to things drawn from the namespace called http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt-ex-dt#, which is a sibling document to this document itself, containing XML Schema datatype definitions used in this document. This is conventional in many DAML+OIL+DT documents, as they will have a separate document containing XML Schema datatype definitions.

The final declaration states that unprefixed elements refer to http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt-ex# , i.e., the location of this document itself.

If you look at the bottom of this document, you'll see the matching closing tag, </rdf:RDF>.

Housekeeping

The first thing we do inside this RDF document is to assert that this is an ontology.

<daml:Ontology rdf:about="">

This assertion is formulaic; the about attribute will typically be empty, indicating that the subject of this assertion is this document.Same-document reference

Then we give a couple of properties of this ontology for documentation purposes:

  <daml:versionInfo>$Id: daml+oil+dt-ex.daml,v 4 2001/02/20 pfps $</daml:versionInfo>
  <rdfs:comment>
    An example ontology, with data types taken from XML Schema
  </rdfs:comment>

followed by

  <daml:imports rdf:resource="http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt">

Inside the Ontology element, we list any imported ontologies (using imports properties). This particular ontology depends only on the standard DAML+OIL+DT ontology (used in the namespace definitions above).

Note that this (imports) tag is an empty element; the same tag starts and ends the element, denoted by the trailing "/" just before the closing ">".

</daml:Ontology>

Defining Classes

Now, we begin our ontology definitions. In order to describe objects, it is useful to define some basic types. If we are working in a domain of animals, we will want to define a kind of thing called animal. To do this, we use a Class tag. Class

<daml:Class rdf:ID="Animal">

This asserts that there is an abstract class known as Animal. It doesn't say anything else about animal other than specifying an identifier. It is also not (necessarily) the sole source of information about Animals; we will see below how we can add to a definition made elsewhere.

However, by saying that its ID is Animal, we make it possible for others to refer to the definition of Animal we're giving here. (This is done using the uri of the containing page followed by #Animal.)

  <rdfs:label>Animal</rdfs:label>
  <rdfs:comment>
    This class of animals is illustrative of a number of ontological idioms.
  </rdfs:comment>

These two lines introduce a label -- a brief identifier of the enclosing element, suitable for graphical representations of RDF, etc. -- and a comment -- a natural language (English, in this case) description of the element within which it is included. Neither a label nor a comment contributes to the logical interpretation of the language.

</daml:Class>

DAML+OIL+DT divides the world up into abstract objects, i.e., objects that are created, like the person Fred; and datatype values, i.e., values that come from XML Schema datatypes, like the integer 4. Here we are creating an abstract class. Later we will see examples of datatypes.

There are two types of animals, Male and Female.

<daml:Class rdf:ID="Male">
  <rdfs:subClassOf rdf:resource="#Animal"/>
</daml:Class>

The subClassOf element asserts that its subject -- Male -- is a subclass of its object -- the resource identified by #Animal. SubClassOf

<daml:Class rdf:ID="Female">
  <rdfs:subClassOf rdf:resource="#Animal"/>
  <daml:disjointWith rdf:resource="#Male"/>
</daml:Class>

Some animals are Female, too, but nothing can be both Male and Female (in this ontology) because these two classes are disjoint (using the disjointWith tag)

It perfectly admissible for a class to have multiple superclasses: A Man is a Male Person

<daml:Class rdf:ID="Man">
  <rdfs:subClassOf rdf:resource="#Person"/>
  <rdfs:subClassOf rdf:resource="#Male"/>
</daml:Class>

...and a Woman is a Female Person.

<daml:Class rdf:ID="Woman">
  <rdfs:subClassOf rdf:resource="#Person"/>
  <rdfs:subClassOf rdf:resource="#Female"/>
</daml:Class>

As always in DAML+OIL+DT, conjoining statements without an explicit connective means that the statements must be read conjunctively, in this case: Woman is a subclass of Person and is a subclass of Female.

Defining Properties

Next, we define a property. A property -- or binary relation -- connects two items. As with classes, DAML+OIL+DT properties are generally divided into two sorts -- those that relate abstract objects to other abstract objects and those that relate abstract objects to datatype values. The former belong to daml:AbstractProperty and the latter belong to daml:DatatypeProperty. It is possible to use properties that are not sorted this way, but very little can be done with such properties.

In this case, we're defining the hasParent relation which will be used to connect two animals. Property

<daml:AbstractProperty rdf:ID="hasParent">

The property definition begins by stating that there is a property called hasParent. Note, however, that this is not a closing tag; there's more to this definition. (There is a matching </Property> tag below.)

  <rdfs:domain rdf:resource="#Animal"/>

Like all embedded elements, this is understood to describe its enclosing element. So, this element describes the Property whose ID is hasParent. It says that the domain of the hasParent relation is Animal. That is, we're defining hasParent as a property that applies to animals.

  <rdfs:range rdf:resource="#Animal"/>

Similar to the domain, we also declare the range of the hasParent relation to be Animal. That is, we're defining hasParent as a property whose value can only be animals.

It is allowed in DAML+OIL+DT to state multiple ranges. Again, such multiple statements must be read conjunctively: the values of the property must satisfy all the range statements (and similar for multiple domain statements). Note that in this aspect, DAML+OIL+DT departs from the RDF Schema semantics for domain and range. See the reference document for more details. (Note the comment below which points out that there is an better alternative for such domain and range restrictions.) We do this by asserting that there's a thing which is a domain -- the things to which this property applies, ie. the things that can have parents -- and saying that this domain is the resource known as #Animal. What is the resource attribute? It is a reference to something. Note that the ID attributes that we created for each entry until now serve as reference-able descriptions; resource refers to such descriptions. In this case, it refers to names in this document, since its reference begins with a #.

</daml:AbstractProperty>

That's all we have to say about this Property (whose ID = hasParent).

Next, we state that hasFather is a property that is a kind of hasParent property, i.e., x's father is also x's parentsubProperty. In addition, range is used to ensure that x's father must be a Male.

<daml:AbstractProperty rdf:ID="hasFather">
  <rdfs:subPropertyOf rdf:resource="#hasParent"/>

  <rdfs:range rdf:resource="#Male"/>

</daml:AbstractProperty>
(Note the comment below which points out that there is an better alternative for such range restrictions.)

Properties that relate abstract properties to datatype values are members of DatatypeProperty. For example, we might want to provide a shoesize property, which is provides at most a single shoe size, which is a decimal number. We reference the XML Schema datatype decimal by referring to its standard location.

<daml:DatatypeProperty rdf:ID="shoesize">
  <rdfs:comment>
    shoesize is a DatatypeProperty whose range is xsd:decimal.
    shoesize is also a UniqueProperty (can only have one shoesize)
  </rdfs:comment>
  <rdf:type rdf:resource="http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt#UniqueProperty"/>
  <rdfs:range rdf:resource="http://www.w3.org/2000/10/XMLSchema#decimal"/>
</daml:DatatypeProperty>

Similarly we create an age property, which maps into XML Schema non-negative integers.

<daml:DatatypeProperty rdf:ID="age">
  <rdfs:comment>
    age is a DatatypeProperty whose range is xsd:decimal.
    age is also a UniqueProperty (can only have one age)
  </rdfs:comment>
  <rdf:type rdf:resource="http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt#UniqueProperty"/>
  <rdfs:range rdf:resource="http://www.w3.org/2000/10/XMLSchema#nonNegativeInteger"/>
</daml:DatatypeProperty>

Defining property restrictions

Now we'll define a Class with some attributes.

<daml:Class rdf:ID="Person">

This element describes a kind of thing called a Person, and is referenceable as such.

  <rdfs:subClassOf rdf:resource="#Animal"/>

A Person is a kind of Animal (referring to the definition of Animal above).

The next few lines describe a class-specific range restriction. In particular, the parent of a Person is also a Person.

  <rdfs:subClassOf rdf:resource="#Animal"/>
  <rdfs:subClassOf>
    <daml:Restriction>
      <daml:onProperty rdf:resource="#hasParent"/>
      <daml:toClass rdf:resource="#Person"/>
    </daml:Restriction>
  </rdfs:subClassOf>

What happens here is that the Restriction defines an anonymous class, namely the class of all things that satisfy the restriction. In this case: the class of all things whose parent is a Person. We then demand that the class Person is a subClassOf this (anonymous) class. In other words: we demand that every Person must satisfy this Restriction, which in this case amounts to demanding that Persons have only Persons as their parents.

The syntax used here is a cliche, i.e., it is always used as shown, except for (i) the name of the resource in the OnProperty element, which will give the name of the Property to be restricted, and (ii) the resource associated with the toClass element, which will give the name of the Class to which the Property is restricted.

Note: When restricting the range of a property, as we are doing here, there is an important difference between using a toClass restriction and using rdfs:range (as we did for the hasFather property). An rdfs:range element has a global scope: any use of the hasFather property for any class must always yield a male. A toClass restriction (as used in the Person class) on the other hand has a local scope: the parent of a person must be person, but the parent of any other class (e.g. the parent of an elephant) need not be a person.

Note: In general, stating toClass restrictions locally to a class will result in ontologies that are more extendable (and therefore more reusable) then those using rdfs:range and rdfs:domain. The latter two make global assertions that must be obeyed by anyone who will ever want to use the property concerned, applied to any class whatsoever. Because of this, using local Restriction elements is considered much better DAML+OIL+DT style than using global rdfs:domain and rdfs:range.

The class Person comes with two other examples of restrictions :

  <rdfs:subClassOf>
    <daml:Restriction daml:cardinality="1">
      <daml:onProperty rdf:resource="#hasFather"/>
    </daml:Restriction>
  </rdfs:subClassOf>
  <rdfs:subClassOf>
     <daml:Restriction>
       <daml:onProperty rdf:resource="#shoesize"/>
       <daml:minCardinality>1</daml:minCardinality>
     </daml:Restriction>
  </rdfs:subClassOf>

This requires that any person must have exactly 1 father and at least one shoe size. Again, this is done by first using a Restriction to define an anonymous class (in this case the class of all things that have exactly one father), and then demanding that Person is a subClassOf this anonymous class (ie demanding that every Person satisfies this Restriction).

The two restrictions above have slightly different layouts, but they both result in similar RDF. Either layout can be used at will.Alternative syntax.

Again, the above restrictions have only local scope: the above only enforces that a Person has exactly 1 father. This still leaves open the (unlikely) possibility that other classes have more or fewer than one father.

Besides toClass and cardinality, other restrictions are possible. These are all discussed reference document on DAML+OIL+DT.

</daml:Class>

That's the end of the Person class.

A key feature of any web-based ontology language is that statements about entities such as classes and properties can be distributed among different locations. For example, if we wanted to add to the Animal class (defined above) that all animals have exactly 2 parents, we need not modify the above statement, but we can simply add the following, referring to the statement with its ID:

<daml:Class rdf:about="#Animal">
  <rdfs:comment>
    Animals have exactly two parents, ie:
    If x is an animal, then it has exactly 2 parents 
    (but it is NOT the case that anything that has 2 parents is an animal).
  </rdfs:comment>
  <rdfs:subClassOf>
    <daml:Restriction daml:cardinality="2">
      <daml:onProperty rdf:resource="#hasParent"/>
    </daml:Restriction>
  </rdfs:subClassOf>
</daml:Class>

Such an assertion "about" the class Animals has exactly the same logical status as the assertions made within the <daml:Class rdf:ID="Animal"> element about vs. ID.

Note that if this statement had lived in another file, we should have referred to the class Animal with a fully qualified URL: rdf:about="http://www.daml.org/2000/12/DAML+OIL+DT-ex.daml#Animal"

The cardinality property specifies a precise cardinality. But sometimes we want to bound the cardinality without precisely specifiying it. A person may have zero or one spouse, but no more:

<daml:Class rdf:about="#Person">
  <rdfs:subClassOf>
    <daml:Restriction daml:maxcardinality="1">
      <daml:onProperty rdf:resource="#hasSpouse"/>
    </daml:Restriction>
  </rdfs:subClassOf>
</daml:Class>

Of course, a minimal value for the cardinality of a property can be expressed in a similar way.

If no minimum cardinality is specified, a minimum cardinality of 0 is assumed. Thus, <Restriction daml:mincardinality="0"> would not need to be asserted.

A more sophisticated version of a cardinality constraint on a property not only specifies a maximum, minimum or precise number of values for that property, but also enforces the type that these property values must have:

<daml:Class rdf:about="#Person">
  <rdfs:subClassOf>
    <daml:Restriction daml:maxcardinalityQ="1">
      <daml:onProperty rdf:resource="#hasOccupation"/>
      <daml:hasClassQ rdf:resource="#FullTimeOccupation"/>
    </daml:Restriction>
  </rdfs:subClassOf>
</daml:Class>

This states that a Person may have at most one occupation that is a FullTimeOccupation. (This still allows for the possibility that they may have multiple jobs of other types than FullTimeOccupation).

Of course, such qualified cardinality constraints can be stated as well for minimal cardinalities and exact cardinalities.

Notations for properties

The next several annotations illustrate various notations for properties:

HasMother is defined similarly to hasFather, but using a variant notation. A UniqueProperty is one with cardinality 1, so we can omit the cardinality sub-element from HasMother's definition.

<daml:UniqueProperty rdf:ID="hasMother">
  <rdfs:subPropertyOf rdf:resource="#hasParent"/>
  <rdfs:range rdf:resource="#Female"/>
</daml:UniqueProperty>

Since a UniqueProperty has cardinality 1, each subject uniquely identifies the object (value) of the property (ie. the identity of a person determines their mother). Conversely, an UnambiguousProperty is a property whose object uniquely identifies its subject. (The inverse of any UniqueProperty is always an UnambiguousProperty).

Notice that UniqueProperty and UnambiguousProperty specify global cardinality restrictions. That is, no matter what class the property is applied to, the cardinality constraints must hold, unlike the cardinality restrictions illustrated above, which are part of a class element, and are only enforced on the property when applied to that class.

If x's parent is y, then y is x's child. This is defined using the inverseOf tag.

<daml:AbstractProperty rdf:ID="hasChild">
  <daml:inverseOf rdf:resource="#hasParent"/>
</daml:AbstractProperty>

The hasAncestor and descendent properties are transitive versions of the hasParent and hasChild properties.

<daml:TransitiveProperty rdf:ID="hasAncestor">
  <rdfs:label>hasAncestor</rdfs:label>
</daml:TransitiveProperty>

<daml:TransitiveProperty rdf:ID="descendant"/>

Note that this only states that hasAncestor is transitive, but not yet that hasAncestor is the transitive version of hasParent (and ditto for hasDescendant and hasChild). DAML+OIL+DT would need additional language constructs to enforce these connections.

Sometimes, we like to refer to mothers using the synonym mom. The tag samePropertyAs allows us to establish this synonymy:

<daml:AbstractProperty rdf:ID="hasMom">
  <daml:samePropertyAs rdf:resource="#hasMother"/>
</daml:AbstractProperty>

Notations for classes

Classes, too, can be annotated in various ways:

<daml:Class rdf:ID="Car">
  <rdfs:comment>no car is a person</rdfs:comment>

We want to state that cars can never be persons, in other words: cars are a subclass of non-persons. The thing that Car is a subClassOf (ie non-persons) could in principle be specified using a resource= attribute. In this case, however, there is no pre-existing succinct name for the thing we want (the class of non-persons). We build this by introducing a new -- anonymous -- Class definition described using the complementOf tag:

  <rdfs:subClassOf>
    <daml:Class>
      <daml:complementOf rdf:resource="#Person"/>
    </daml:Class>
  </rdfs:subClassOf>

In other words: Car is a Class that is a specialization of another (anonymous) Class, namely the Class consisting of all things except Persons.

</daml:Class>
... and this finishes the definition of the class Car.

In effect, the above makes the class Car disjoint from the class Person (since Car is declared to be a subClass of the complementOf Person). Because such disjointness statements among classes occur very frequently, DAML+OIL+DT has a specific vocabulary for this special case. The same fact could have been stated using the disjointWith tag that we already saw above in the definition of Female.

An even more compact idiom is to state that a whole set of classes are all pairwise disjoint. Rather than stating the individual disjointness relations, this can be stated for a set of classes in a single statement:

<daml:Disjoint rdf:parseType="daml:collection">
  <daml:Class rdf:about="#Car"/>
  <daml:Class rdf:about="#Person"/>
  <daml:Class rdf:about="#Plant"/>
</daml:Disjoint>

Note that the Disjoint element contains multiple subelements. The parseType="daml:collection" indicates that these subelements are to be treated as a unit (namely as a single collection) RDF extension.

Besides stating that classes are disjoint,

We can also identify a Class with the disjoint union of a set of other classes. In this case, we identify the Class Person with the disjoint union of the Classes Man and Woman.

<daml:Class rdf:about="#Person">
  <rdfs:comment>every person is a man or a woman</rdfs:comment>
  <daml:disjointUnionOf rdf:parseType="daml:collection">
    <daml:Class rdf:about="#Man"/>
    <daml:Class rdf:about="#Woman"/>
  </daml:disjointUnionOf>
</daml:Class>

This is also another example of further specifying a previously defined element by using the about attribute. Note also that disjointUnionOf again uses the non-standard parseType="daml:collection" construct.

We have already seen that we can construct a new class by taking the complementOf another class. In the same way, we can construct classes out of the intersection of other classes:

<daml:Class rdf:ID="TallMan">
  <daml:intersectionOf rdf:parseType="daml:collection">
    <daml:Class rdf:about="#TallThing"/>
    <daml:Class rdf:about="#Man"/>
  </daml:intersectionOf>
</daml:Class>
This states that the class TallMan is exactly equal to the intersection of Man and TallThing. (See below for the definition of the class TallThing). Note that we can take the intersectionOf an arbitrary number of classes (parseType="daml:collection").

Similarly, we can construct a class as the unionOf a set of classes.

As already indicated, the intersectionOf construction makes the named class exactly equal to the result of the intersection. This construction is frequently used as an idiom if we want to state not only necessary but also sufficient conditions for a class. For example, a MarriedPerson is a Person with a spouse, but also vice versa: any Person with a spouse is a MarriedPerson. Such necessary and sufficient conditions can be enforced using intersectionOf:

<daml:Class rdf:ID="MarriedPerson">
  <daml:intersectionOf rdf:parseType="daml:collection">
    <daml:Class rdf:about="#Person"/>
    <daml:Restriction daml:cardinality="1">
      <daml:onProperty rdf:resource="#hasSpouse"/>
    </daml:Restriction>
  </daml:intersectionOf>
</daml:Class>

Note the use of the cardinality Restriction to specify an anonymous class. This anonymous class (the class of all things that have exactly one spouse) is intersected with the Person class to yield exactly all Persons that have one spouse.

Just as for properties, a mechanism exists for declaring synonyms for classes:

<daml:Class rdf:ID="HumanBeing">
  <daml:sameClassAs rdf:resource="#Person"/>
</daml:Class>

Using User-defined Datatypes

It is also possible to use user-defined datatypes in DAML+OIL+DT. Suppose we wanted to distinguish between different classes of people by their ages. We would create several XML Schema datatype definitions in a separate file, such as http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt-ex-dt, which contains

<xsd:simpleType name="over17">
  <!-- over17 is an XMLS datatype based on positiveIntege -->
  <!-- with the added restriction that values must be >= 18 -->
  <xsd:restriction base="xsd:positiveInteger">
  <xsd:minInclusive value="18"/>
  </xsd:restriction>
</xsd:simpleType>

<xsd:simpleType name="over59">
  <!-- over59 is an XMLS datatype based on positiveIntege -->
  <!-- with the added restriction that values must be >= 59 -->
  <xsd:restriction base="xsd:positiveInteger">
  <xsd:minInclusive value="60"/>
  </xsd:restriction>
</xsd:simpleType>

Then we could reference elements of this file in DAML+OIL+DT restrictions, as in

<daml:Class rdf:ID="Adult">
  <daml:intersectionOf rdf:parseType="daml:collection">
    <daml:Class rdf:about="#Person"/>
    <daml:Restriction>
      <daml:onProperty rdf:resource="#age"/>
      <daml:hasClass rdf:resource="http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt-ex-dt#over17"/>
    </daml:Restriction>
  </daml:intersectionOf>
</daml:Class>

<daml:Class rdf:ID="Senior">
  <daml:intersectionOf rdf:parseType="daml:collection">
    <daml:Class rdf:about="#Person"/>
    <daml:Restriction>
      <daml:onProperty rdf:resource="#age"/>
      <daml:hasClass rdf:resource="http://www.cs.man.ac.uk/~horrocks/daml+oil/datatypes/daml+oil+dt-ex-dt#over59"/>
    </daml:Restriction>
  </daml:intersectionOf>
</daml:Class>

Defining individuals

We can also define individuals, e.g., Adam, a person of age 13 and shoesize 9.5:

<Person rdf:ID="Adam">
  <rdfs:label>Adam</rdfs:label>
  <rdfs:comment>Adam is a person.</rdfs:comment>
  <age><xsd:integer rdf:value="13"/></age>
  <shoesize><xsd:decimal rdf:value="9.5"/></shoesize>
</Person>
Note that to use datatype values, we had to provide an XML Schema datatype along with the value. This datatype is used to parse the lexical representation into an actual value.

A Person has a property called hasHeight, which is a Height. (hasHeight is a Property, or relation; Height is a Class, or kind of thing.)

<daml:AbstractProperty rdf:ID="hasHeight">
  <rdfs:range rdf:resource="#Height"/>
</daml:AbstractProperty>

Height is a Class described by an explicitly enumerated set. We can describe this set using the oneOf element. Like disjointUnionOf, oneOf uses the RDF-extending parsetype="daml:collection". RDF extension

<daml:Class rdf:ID="Height">
  <daml:oneOf rdf:parseType="daml:collection">
    <Height rdf:ID="short"/>
    <Height rdf:ID="medium"/>
    <Height rdf:ID="tall"/>
  </daml:oneOf>
</daml:Class>

Finally, TallThing is exactly the class of things whose hasHeight has the value tall:

<daml:Class rdf:ID="TallThing">
  <daml:sameClassAs>
    <daml:Restriction>
      <daml:onProperty rdf:resource="#hasHeight"/>
      <daml:hasValue rdf:resource="#tall"/>
    </daml:Restriction>
  </daml:sameClassAs>
</daml:Class>
>From the inside out, this says first that TallThings must have the value tall as value for their hasHeight property, ie having the value tall as your height is a necessary condition for being a TallThing. Secondly, we say that TallThing is exactly the same class as the the class of all such objects (ie all objects having tall as their value for hasHeight), in other words: besides being necessary, this condition is also sufficient for being a TallThing.

Consider what would have happened if we had used subClassOf instead of sameClassAs. This would have resulted in a necessary but not sufficient condition for the definition of the class TallThing. Thus, a necessary-only and a necessary-and-sufficient class definition now only differ simply in their outermost element: either a subClassOf or a sameClassAs as element, respectively.

Finally, we end our specfication with the rdf:RDF element.

</rdf:RDF>

Acknowledgements

This draft draws on the work of many of the researchers in the DAML project, and from discussion with and review by Jim Hendler, Tim Berners-Lee, Ralph R. Swick, Pat Hayes, Drew McDermott, Stefan Decker, Richard Fikes, Jeff Heflin, and Ian Horrocks.




A minimalist survival guide to XML

This appendix is intended for those unfamiliar with RDF. It contains only enough information to enable you to read the annotated DAML+OIL+DT markup example, and is not intended as a complete introduction to RDF, XML, or any other of the technologies on which DAML+OIL+DT is based. See the suggested readings below for more information.

RDF is built on XML, which makes use of tags to structure information. Here are some example tags:

<aTag>...</aTag>

<anEmptyTag/>

<anotherTag with="an attribute">...</anotherTag>


<aTag>with <anemptyTag/> inside it</aTag>



<tags>and<moreTags>and<yetmoreTags>and...</yetmoreTags></moreTags></tags>

The first thing after the open angle bracket is the tag name. The whole tag is often referred to by this name. So

<Class ID="Animal">

is a Class tag.

A tag ends with a closing angle bracket.

Some tags are start tags, and have matching end tags. The end tag has the same tag name as the opening tag, but begins with </ rather than simply <. For example,

<Class ID="Animal">

would be closed by the matching end tag

</Class>

From an opening tag to its matching closing tag is an element. Other tags can be embedded inside the element, but all such embedded elements must be closed inside the enclosing element. So <rdf:RDF> would begin an element that runs until an </rdf:RDF>. In this case, anything between the <rdf:RDF> and the matching </rdf:RDF> would be enclosed in the scope of this element.

An alternate way to specify an element that has nothing between its opening and its closing tag is to use a single tag with a slash immediately before the closing angle-bracket. Thus, the self-closing tag

<Class ID="Animal"/>

is the same as

<Class ID="Animal"></Class>

with nothing inside it.

An opening tag (or a self-closing tag) may contain things other than the tag name. These things after the tag name are attributes. Each attribute has a name, an equal sign, and an attribute value (generally enclosed in double quotes). So, for example, in the Class tag above,

ID="Animal"

is the attribute,

ID

is the attribute name, and

"Animal"

is the attribute value. Attributes are read as properties of the element in which they appear.

A minimalist survival guide to RDF

An RDF document is a collection of assertions in subject verb object (SVO) form. Within the obligatory RDF declaration (typically a tag that begins something like <rdf:RDF ...), each topmost element is the subject of a sentence. The next level of enclosed elements represent verb/object pairs for this sentence:

<Class ID="Male">
  <subClassOf resource="#Animal"/>
</Class>

Male is a subclass of Animal.

<Class ID="Female">
  <subClassOf resource="#Animal"/>
  <disjointWith resource="#Male"/>
</Class>

Female is a subclass of Animal AND Female is disjoint from Male. The single subject -- Female -- is used to begin each of the verb-object assertions

 <subClassOf resource="#Animal"/>
 

and

<disjointWith resource="#Male"/>

A few attributes here require explanation.

ID creates a referenceable name, corresponding to the attribute value. So, for example, ID="Male" means that you can refer to Male and mean the thing described by the Class element above. Similarly, Female is a referenceable name.

The resource attribute, then, is simply a reference to such a name. In

<disjointWith resource="#Male"/>

the resource attribute is used to indicate that the object of the assertion "Female is disjoint from" is the thing identified with the name Male. Note the prepended # to refer to the name. This indicates a reference to a name within the same containing document, i.e., a local name. It is also possible (e.g., by prepending a url before the #) to refer to a name defined elsewhere.

In the above example, each verb tag is self-closing. It is also possible to embed elements inside these verb elements, making objects which are themselves the subjects of subordinate clauses. This causes an alternation of subject verb subject verb ... sometimes called RDF striped syntax.




Notes

xmlns:rdf
The namespace prefix rdf is arbitrary here; you can call the namespace associated with http://www.w3.org/1999/02/22-rdf-syntax-ns# whatever you want. Since this is the conventional namespace for rdf syntax, rdf is a common way to spell this prefix.
unprefixedAttrs
Unprefixed attribute names are not associated with the default namespace name the way unprefixed element names are. See myth #4 in Namespace Myths Exploded.
Same-document reference
See section 4.2 Same-document References of [URI].
Class
daml:Class is now a separate class from rdfs:Class. Previously the two had the same semantics or were the same object.
SubClassOf
Strictly speaking, daml:subClassOf is declared as a subclass of and rdfs:subClassOf. However, the semantics of daml:subClassOf and rdf:subClassOf are exactly the same. To promote backward compatability with RDF Schema, we have used daml:Class instead of daml:Class.
Property
Again, daml:AbstractProperty is used instead of daml:Property to achieve maximal backward compatability with RDF agents.
subProperty
A similar remark applies here as to Property.
RDF extension
This is a proper extension of RDF 1.0 syntax. Existing tools (at the time of this writing) are unlikely to support this.
Alternative syntax
The relevant part of the RDF specification is in the section on abbreviated syntax where it says: "Three forms of abbreviation are defined for the basic serialization syntax. The first is usable for properties that are not repeated within a Description and where the values of those properties are literals".
about vs. ID
In fact, using either "about=" or "ID=" results in exactly the same set of RDF triples, and perforce the DAM+OIL meaning of these different notations is the same.

References and Suggested Reading

[DAML+OIL+DT]
Official definition of the language in RDF Schema form at DAML+OIL+DT.daml,
also: example ontology
[XML]
Extensible Markup Language (XML) 1.0
W3C Recommendation Feb 1998
what you really need to know:
more background
Extensible Markup Language (XML) at W3C
[URI]
Uniform Resource Identifiers (URI): Generic Syntax
IETF Draft Standard August 1998 (RFC 2396) T. Berners-Lee, R. Fielding, L. Masinter
what you really need to know:
more background
Web Naming and Addressing Overview (URIs, URLs, ...) at W3C
[XMLNS]
Namespaces in XML
W3C Recommendation Jan 1999
what you really need to know:
more background
Extensible Markup Language (XML) at W3C
[RDF]
Resource Description Framework (RDF) Model and Syntax Specification
World Wide Web Consortium Recommendation, 1999 Lassila, Swick [eds]
http://www.w3.org/TR/1999/REC-rdf-syntax-19990222

background: RDF: Resource Description Framework at W3C

[RDFS]
Resource Description Framework (RDF) Schema Specification 1.0
W3C Candidate Recommendation 27 March 2000.

$Revision: 4.1$ of $Date: 2001/02/26$.