a proposed format for portable ontologies

Tom Gruber <Gruber@Sumex-AIM.Stanford.edu>
Message-id: <2922600585-1924836@KSL-Mac-69>
Date: Wed, 12 Aug 92  02:29:45 PDT
From: Tom Gruber <Gruber@Sumex-AIM.Stanford.edu>
To: srkb@ISI.EDU
Subject: a proposed format for portable ontologies
The DARPA knowledge sharing effort is divided into four major working groups.
The Interlingua group is specifying a declarative language for knowledge
called KIF.  They are worried about giving a solid semantics and clean,
elegant syntax for logic.  The External Interfaces group is specifying a
protocol for the communication of knowledge among programs, called KQML.
They are worried about the transport of messages and the speech acts of
agents, among other things.  The KR Systems group is specifying a common
language called KRSS for the KL-ONE family of description logics.  The SRKB
group is not specifying anything just yet.  We are studying the problem of
knowledge sharing, and are focusing on content-specific ontologies as the
specification mechanism.  However, in service of our task we need some way to
describe, analyze, compare, and develop ontologies that we can share.
For that purpose we have developed a system called Ontolingua.

Ontolingua is a Lisp (CLOS) program that translates definitions in a portable
format into a set of implemented systems.  It allows one to read or write
ontologies from shared files, yet also run them in one's own representation
tool.  The code is freely available via FTP and is continually being improved
in response to user feedback.  A full-length technical report and reference
manual are available, and a mail distribution list will support a user

Ontolingua definitions are basically KIF, wrapped in some Lispy syntax to
facilitate modularity and explore features not yet in KIF (e.g., theories).
It is designed to translate into the class of representation systems that are
called object-centered or frame systems, but it also translates into
predicate calculus languages.  It has been recently extended to support the
full set of primitives in the KRSS specification (which reflects the
capabilities of systems such as LOOM, CLASSIC, and BACK).  A set of
translators already exist from Ontolingua into LOOM, Epikit, Algernon, and
pure KIF.  (Others are in the works to translate _from_ systems like these
into Ontolingua.)

Since Ontolingua is translating from a very expressive language, KIF, into
restricted languages, such as KRSS, there are problems of incompleteness.
First, KIF offers several ways to say logically equivalent things.  Second,
KIF allows one to say things that cannot be stated in many object-centered
systems.  The approach taken in Ontolingua is to identify a pallette of
things-to-say that _are_ supported in object-centered systems, and to specify
a format for saying these things that can be translated.  The pallette is a
set of definitions of terms used to organize knowledge in object-centered
representations (e.g., subclass-of, instance-of, domain, range, arity,
slot-value-type, slot-cardinality, subclass-partition).  These terms are
defined in an ontology, called the Frame Ontology.  The translatable format
is a syntactic restriction on the KIF language (e.g., only first-order
relations except those defined in the frame ontology).  The resulting
language, KIF + the Frame Ontology, is a language for defining portable

The precise syntax of this language is given in the KIF 3.0 specification and
the Ontolingua reference manual.  The set of supported second-order relations
is documented in the Frame Ontology.  We will give the briefest of
introductions here, and refer the reader to the documentation and the long
example ontology that follows for more information.

For more information, send mail to gruber@sumex-aim.stanford.edu.

Quick Introduction to Ontolingua definitions

An ontology file is made up of definitions of classes, relations, functions,
distinguished instances, and axioms that relate these terms.  Classes are
logically equivalent to unary relations, and functions are specializations of
relations (which have one extra argument for the value).  Classes, relations,
and functions are also objects that can be arguments to certain second-order
relations.  These and other commitments are formalized and justified in the
Frame Ontology.

A relation is defined with a form like the following:

(define-RELATION relation-name (?arg1 ?arg2)
  "documentation string"
  :def (and (domain-restriction ?arg1)
            (range-restriction ?arg2)
            (predicate-relating-args ?arg1 ?arg2)))

The sentence after the :def is a KIF sentence mentioning the arguments.  Thus
one can define a relation by stating logical constraints over its arguments.
They are NECESSARY conditions, which must hold if the relation holds over
some arguments.  It is also possible to state sufficient conditions, or any
combination.  Restrictions on the value of the first argument of a binary
relation are effectively domain restictions, and those on the second argument
of a binary relation are range restrictions.  There can be more than two
arguments to a relation, and complex logical expressions describing their
relationships.  A relation only holds over objects when the argument
restrictions are satified, and when a relation is asserted to hold on some
arguments, these conditions must be met.

A class is defined with a very similar form, where there is exactly one
argument, called the instance variable.

(define-CLASS class-name (?instance)
  "documentation string"
  :def (and (superclass ?instance)
            (other-properties-of-instances ?instance)))

The :def sentence describes those things that must be true of instances of
the class.  Unary predicates applied to the instance variable specify
superclasses of the class being defined.  Other properties can be stated
using KIF sentences mentioning the instance variable.

A function is defined like a relation, with a slight variation in syntax: 

(define-FUNCTION function-name (?arg1 ?arg2) :-> ?value
  "documentation string"
  :def (and (argument-restriction ?arg1)
            (range-restriction ?value))
  :lambda-body (function1 (function2 ?arg1) (function3 ?arg2)))

The arguments to a function are constrained as in relations; the function is
only defined on arguments that satisfy these domain constraints.
A restriction on the range of the function is specified with a sentence
constraining the value variable.  A function of N arguments is equivalent to
a relation of N+1 arguments with the additional constraint that there is at
most one value for a given binding for the arguments.

When a side-effect-free functional expression is known for determining the
value of a function from values of its arguments, then it can be given as a
KIF term expression following :lambda-body.

In any of the defintional forms, one may also write KIF sentences that help
define the class, relation, or function but do not mention the argument
variables.  These are stand-alone axioms, labeled with the :axiom-def
keyword.  Such axioms often use special second-order relations from the frame
ontology that take functions, relations, and classes as arguments.  For

(define-class C (?i)
  "The class C is a subclass of P and is divided into three disjoint
subclasses X, Y, and Z."
  :def (P ?i)
  :axiom-def (exhaustive-subclass-partition C (setof X Y Z)))

This exhaustive-subclass-partition statement says that C is completely
divided into three subclasses, which are mutually disjoint.  This is much
more succinct than the expanded KIF axiom:

(and (=> (C ?i) (or (X ?i) (Y ?i) (Z ?i)))
     (=> (X ?i) (C ?i))
     (=> (Y ?i) (C ?i))
     (=> (Z ?i) (C ?i))
     (=> (X ?i) (not (Y ?i)))
     (=> (X ?i) (not (Z ?i)))
     (=> (Y ?i) (not (X ?i)))
     (=> (Y ?i) (not (Z ?i)))
     (=> (Z ?i) (not (X ?i)))
     (=> (Z ?i) (not (Y ?i))))

1*For those who like wall charts, here is a BNF grammar for Ontolingua.

<definition> :== <relation-def> | <class-def> | <function-def> |
                 <instance-def> | <axiom-def> | <theory-def>

<relation-def> :== (DEFINE-RELATION <relation-name> (<var> [<var>]*)
                      {:def | :iff-def} <sent-with-arg-vars>
                      [:constraints <sent-with-arg-vars>]
                      [:equivalent <sent-with-arg-vars>]
                      [:sufficient <sent-with-arg-vars>]
                      [:default-constraints <sent-with-arg-vars>]
                      [:axiom-def <sent-without-arg-vars>]
                      [:axiom-constraints <sent-without-arg-vars>]
                      [:theory <theory-name>])
                      [:issues <issue-tree>]

<class-def> :== (DEFINE-CLASS <class-name> (<var>)
                      {:def | :iff-def} <sent-with-arg-vars>
                      [:constraints <sent-with-arg-vars>]
                      [:equivalent <sent-with-arg-vars>]
                      [:sufficient <sent-with-arg-vars>]
                      [:default-constraints <sent-with-arg-vars>]
                      [:axiom-def <sent-without-arg-vars>]
                      [:axiom-constraints <sent-without-arg-vars>]
                      [:theory <theory-name>])
                      [:issues <issue-tree>]

<function-def> :== (DEFINE-FUNCTION <function-name> (<var> [<var>]*) [:-> <var>]
                      [{:def | :iff-def} <sent-with-arg-vars>]
                      [:constraints <sent-with-arg-vars>]
                      [:axiom-def <sent-without-arg-vars>]
                      [:axiom-constraints <sent-without-arg-vars>]
                      [:lambda-body <term-expression-with-arg-vars>]
                      [:theory <theory-name>])
                      [:issues <issue-tree>]

<instance-def> :== (DEFINE-INSTANCE <instance-name> (<class-name> [<class-name>]*)
                      [:= <term-expression-without-arg-vars>]
                      [:axiom-def <sent-without-arg-vars>])
                      [:theory <theory-name>])
                      [:issues <issue-tree>]

<axiom-def> :== (DEFINE-AXIOM <axiom-name>
                      := <sentence>
                      [:theory <theory-name>])
                      [:issues <issue-tree>]

<theory-def> :== (DEFINE-THEORY <theory-name> ([<theory-name>]*)
                      [:implementation <target-KR-system-name>]
                      [:io-package <Lisp package name>])
                      [:issues <issue-tree>]

<issue-tree> :== ({<string> | <issue-tree>}+)
<docstring> :== <string>
<issue-string> :== <string>
<string>  :== string enclosed in "double quotes", and used as
<var> :== symbol beginning with '?'
<name> :== symbol not beginning with '?' or '@' and used as exactly one of:
  <relation-name> :== <name>
  <class-name> :== <name>
  <function-name> :== <name>
  <instance-name> :== <name>
  <axiom-name> :== <name>
  <theory-name> :== <name>
<sent-with-arg-vars> :== KIF sentence mentioning at least one of the vars in
                         the argument list to the definition
<sent-without-arg-vars> :== KIF sentence mentioning the name of the thing
                            being defined but not the argument vars
<term-expression-with-arg-vars> :== KIF term expression mentioning all of the 
                                    argument variables (but not the value var)
<term-expression-without-arg-vars> :== KIF term expression mentioning the 
                                       function being defined
<sentence> :== any old KIF sentence