Table Of Contents

Previous topic

Getting started with the ELTK

Next topic

KBComponent

This Page

Meta

Background

The core of the ELTK is an interface to the combined data models of the Web Ontology Language (OWL), Resource Description Framework Schema (RDFS) and the Resource Description Framework(RDF). (In the documentation we refer to this combined data model as “OWL+RDFS+RDF”.) That is, using the ELTK, OWL+RDFS+RDF entities are imported into the Python programming environment such that classes, properties and individuals of OWL+RDFS+RDF are created and manipulated alongside Python classes, methods and instances. The goal, then, is to produce Python code that reflects the OWL+RDFS+RDF data model. In this way, the developer can simply use the model at hand (loaded via an ontology and various RDF data graphs), not worrying about ways to re-model OWL+RDFS+RDF in Python. This approach seems quite natural for a Semantic Web effort and may be characterized as a type of ontology-driven software design (cf. [KoideTakeda2006]).

In order to import the model into Python’s OOP environment, we use metaprogramming, or the ability to write code to manipulate code. As inspired by [BabikHluchy2006], the OWL class hierarchy can be directly imported into the Python class hierarchy.

In general OWL+RDFS+RDF is conceptually similar to the object-oriented programming (OOP) paradigm as used in Python. Both OWL+RDFS+RDF and OOP allow for classes and subclasses, inheritance and limited multiple inheritance. RDFS:subClassOf is translated directly to Python class inheritance. Object composition and class instantiation are also similar. RDF:type is translated to Python class instantiation. But the semantics of OWL+RDFS+RDF is inconsistent with that of Python’s in a number of key aspects. For example in most OOP languages, a class instance can only belong to a single class. That is, in Python, the expression type(MyInstance) can only yield a single class. This ensures the behavior of instances based on the associated methods and variables of the instantiated class. In OWL+RDFS+RDF, however, a single individual (corresponding to an instance in OOP) can instantiate multiple classes in the same knowledge base. Thus, to provide a linguistics example, a particular language can be an individual of both EndangeredLanguage and of Koiné at the same time. In the ELTK we manage to integrate this facet of OWL semantics in a fairly seamless way.

Classes in Meta

class eltk.kb.Meta.RDFSResource
RDFSResource is at the top of the metaclass hierarchy, the mother of all types, except for Python’s builtin type.
class eltk.kb.Meta.RDFSClass
RDFSClass represents the notion of class in the RDFS world. OWLClass is a direct sub-type in the meta-taxonomy.
class eltk.kb.Meta.RDFProperty(name, bases, dict)
RDFProperty represents the notion of property in the RDF world.
eltk.kb.Meta.RDFtype
class eltk.kb.Meta.OWLClass(name, bases, dict)
class eltk.kb.Meta.OWLObjectProperty(name, bases, dict)
class eltk.kb.Meta.OWLDatatypeProperty(name, bases, dict)

Illustration of usage

The first thing to do is to import the Meta module:

>>> from eltk.kb.Meta import *

OWLClass

In the simplest case, an OWL class can be created using the new constructor which takes some URI:

>>> Word=OWLClass.new(u'http://mydomain.org/Word')

The new constructor is needed in order to create an instance of metaclass, i.e., Word. Its URI can be called using getURI()

>>> Word.getURI()
>>> http://mydomain.org/Word

The following also works

>>>Word.uri
>>> http://mydomain.org/Word

To demonstrate inheritance, let’s create another class:

>>> Root=OWLClass.new(u'http://mydomain.org/Root')

And then create yet a third class that inherits from both Word and Root:

>>> RootWord=OWLClass.new(u'RootWord',(Word,Root))

>>> issubclass(RootWord,Root)
True
>>> issubclass(RootWord,Word)
True

Instances

Instances of classes (cf. OWL individuals) can be created as follows:

>>> Word = OWLClass.new('http://foo.org/Word')
>>> w1 = Word(u'http://foo.org/word123')
>>> w2 = Word(u'http://foo.org/word456')
>>> type(w1)
<class 'eltk.kb.Meta.Word'>

The getType method is defined to return a list of all types

>>> getType(w1)
[<class 'eltk.kb.Meta.Word'>]
eltk.kb.Meta.getType(obj)

Like Python’s built-in type function, getType returns the type for a metaclass instance. However, unlike built-in type, this function returns a list of types and is, thus, used to simulate the multiple typing found with OWL.

>>> class1 = OWLClass.new(u'http://foo.org/class1')
>>> class2 = OWLClass.new(u'http://foo.org/class2')
>>> i = class1(u'http://foo.org/i',[class2])
>>> getType(i)
[<class '__main__.class2'>, <class '__main__.class1'>]

Properties

There are two kinds of OWL properties: OWLObjectProperty and OWLDatatypeProperty. An OWLObjectProperty can be created as follows

>>> hasConstituent = OWLObjectProperty.new(u'http://foo.org/hasConstituent')

We now create a Morpheme individual in order to demonstrate has the property can be used

>>> Morpheme = OWLClass.new(u'http//foo.org/Morpheme')
>>> m1 = Morpheme(u'http:foo.org/m1')

The property can be used as follows, glossed as “the Word w1 has the Morpheme m1 as its constituent”

>>>  hasConstituent(w1,m1)
(<eltk.kb.Meta.Word object at 0x3a68dd0>, <class 'eltk.kb.Meta.hasConstituent'>, <eltk.kb.Meta.Morpheme object at 0x3a68f90>)

Notice that a 3-tuple (a triple) was returned. That is, when a property is called, a statement in the form of a triple is created.