Introduction to DAML: Part II
Overview
RDF was developed by the W3C at about the same time as XML, and it turns out to be an excellent complement to XML, providing a language for modeling semistructured metadata and enabling knowledge-management applications. The RDF core model is successful because of its simplicity. The W3C also developed a purposefully lightweight schema language, RDF Schema (RDFS), to provide basic structures such as classes and properties.
As the ambitions of RDF and XML have expanded to include things like the Semantic Web, the limitations of this lightweight schema language have become evident. Accordingly, a group set out to develop a more expressive schema language, DARPA Agent Markup Language (DAML). Although DAML is not a W3C initiative, several familiar faces from the W3C, including Tim Berners-Lee, participated in its development.
The previous article in this series presented basic DAML concepts and constructs, explaining the most useful modeling tools DAML puts into the designer's hands.
The present article demonstrates more advanced DAML concepts and constructs, expanding on the Super Sports example.
So far we have looked at how DAML+OIL gives us richer means for expressing constraints in schemas. If this were all it did, it would still be a welcome advance over RDFS. But it happens to go well beyond that. DAML+OIL gives modelers a rich expressiveness. It is not just a schema language but also an ontology language, providing primitives that support the general representation of knowledge. For one thing, it allows one to express classifications by inference rather than by explicitly listing which resources go into which buckets. Behind this simply-stated idea lies a surprising range of nuance for accommodating the classic difficulty of translating the models we hold in our minds to the models we mold in our code.
A Closer Look at daml:Class
The class daml:Class, as we've seen, is a subclass of
rdfs:Class that adds some useful features such as support
for classes defined as enumerations.
Disjoint classes
Another useful feature is the ability to state that one class is disjoint from another. This means that neither of the two classes have any instances in common. So, for example, if we wanted to state that something is either a current product or a discontinued product (in order to keep historical records from the Super sports catalogs), we might write:
<daml:Class rdf:ID="CurrentProduct">
<rdfs:label>Current Product</rdfs:label>
<rdfs:comment>An item currently sold by Super Sports Inc.
at the time of query</rdfs:comment>
</daml:Class>
<daml:Class rdf:ID="DiscontinuedProduct">
<rdfs:label>Discontinued Product</rdfs:label>
<rdfs:comment>An item no longer sold by Super Sports Inc.
at the time of query</rdfs:comment>
<daml:disjointWith rdf:resource="#CurrentProduct"/>
</daml:Class>
The key is the daml:disjointWith property on the
second class. Its value is the first class, thus asserting the two
classes can have no instances in common. The value of this and similar
properties that apply to DAML+OIL classes are known as class
expressions. In this case, the class expression is a very simple
one: the URI of the target class. But DAML+OIL allows us to perform
more complex algebra with class expressions, as we shall see.
The above does not discuss the relationship between these classes
and the product class. We would want to clarify the matter by stating
that all products are either current products or discontinued
products. The daml:disjointUnionOf property allows us to
express this:
<daml:Class rdf:ID="Product">
<rdfs:label>Product</rdfs:label>
<rdfs:comment>An item sold by Super Sports Inc.</rdfs:comment>
<daml:disjointUnionOf parseType="daml:collection">
<daml:Class rdf:ID="CurrentProduct">
<rdfs:label>Current Product</rdfs:label>
<rdfs:comment>An item currently sold by Super Sports Inc.
at the time of query</rdfs:comment>
</daml:Class>
<daml:Class rdf:ID="DiscontinuedProduct">
<rdfs:label>Discontinued Product</rdfs:label>
<rdfs:comment>An item no longer sold by Super Sports Inc.
at the time of query</rdfs:comment>
</daml:Class>
</daml:disjointUnionOf>
</daml:Class>
Which is, of course, equivalent to
<daml:Class rdf:ID="CurrentProduct">
<rdfs:label>Current Product</rdfs:label>
<rdfs:comment>An item currently sold by Super Sports Inc.
at the time of query</rdfs:comment>
</daml:Class>
<daml:Class rdf:ID="DiscontinuedProduct">
<rdfs:label>Discontinued Product</rdfs:label>
<rdfs:comment>An item no longer sold by Super Sports Inc.
at the time of query</rdfs:comment>
</daml:Class>
<daml:Class rdf:ID="Product">
<rdfs:label>Product</rdfs:label>
<rdfs:comment>An item sold by Super Sports Inc.</rdfs:comment>
<daml:disjointUnionOf parseType="daml:collection">
<daml:Class rdf:about="#CurrentProduct"/>
<daml:Class rdf:about="#DiscontinuedProduct"/>
</daml:disjointUnionOf>
</daml:Class>
Note that we omitted the daml:disjointWith property on
CurrentProduct. We no longer need this property, as each
class in a disjoint union must be disjoint with all the others.
Disjoint unions can involve more than two classes. For instance, if Super Sports needs to model products that are not yet offered in their catalogs, they might add this category as follows:
<daml:Class rdf:ID="Product">
<rdfs:label>Product</rdfs:label>
<rdfs:comment>An item sold by Super Sports Inc.</rdfs:comment>
<daml:disjointUnionOf parseType="daml:collection">
<daml:Class rdf:ID="CurrentProduct">
<rdfs:label>Current Product</rdfs:label>
<rdfs:comment>An item currently sold by Super Sports Inc.
at the time of query</rdfs:comment>
</daml:Class>
<daml:Class rdf:ID="DiscontinuedProduct">
<rdfs:label>Discontinued Product</rdfs:label>
<rdfs:comment>An item no longer sold by Super Sports Inc.
at the time of query</rdfs:comment>
</daml:Class>
<daml:Class rdf:ID="UnreleasedProduct">
<rdfs:label>Unreleased Product</rdfs:label>
<rdfs:comment>An item under planning or preparation for
sale by Super Sports Inc., but not yet on sale at the time
of query</rdfs:comment>
</daml:Class>
</daml:disjointUnionOf>
</daml:Class>
And so all products must fall into exactly one of the categories: current, discontinued, or unreleased.