Archive for the ‘Tawny-OWL’ Category

I am pleased to annouce the 1.5.0 release of Tawny-OWL, the fully programmatic ontology construction environment.

As with the 1.4.0 release, there has been quite a long gap between releases. The main change for this release has been the move to the OWL API version 4.

The next release of Tawny will include more extensions to the patterns.

Tawny 1.5.0 is now available on Clojars.

I am pleased to announce this 1.4.0 release of Tawny-OWL. It is with some surprise that I find that it is about 8 months since the last release, which is indicative of the relatively stable state of Tawny.

The main addition to this release has been further support for patterns, which now include what I am calling “facets”, as well as some general functions for grouping the entities created using a pattern with annotations. I have had a lot of discussion about the implementation of this feature and that it should be useful in practice.

The main motivation behind making this release now is the development of a Tawny Tutorial for ICBO 2015. The features are stable for the release are stable, so the release has not been rushed out the door, but I wanted to use them in the tutorial as they really simplify some aspects.

Tawny-OWL 1.4.0 is now available on Clojars.

While I have been working on a manual called Take Wing for Tawny-OWL (http://www.russet.org.uk/blog/3030) for some time, it is far from finished. In the meantime, I am giving a tutorial at this years ICBO, and the slides for this are now relatively advanced, although I have a few more sections and some checking to do. The full tutorial is available (http://github.com/phillord/tawny-tutorial), and I think it offers are fairly comprehensive guide to basic Tawny-OWL usage.

I am fairly pleased with the tutorial as it stands. It is written up as a semantic document using my lentic package (http://www.russet.org.uk/blog/3047) which seems to be working well (although I discovered a few bugs with the asciidoc support in the course of writing the tutorial!).

For anyone who is thinking of coming, the pre-requisities for the tutorial are now online. I am planning to do a large part of the tutorial in a “follow-my-leader” fashion; it’s always difficult to predict the state of the networks at these events, so it would help significantly if at least some of the people coming could work through this short document before hand.

Bibliography

Less than one month after the release of Tawny-OWL 1.2.0 (http://www.russet.org.uk/blog/3018), I am pleased to announce the 1.3.0 release. This is a much smaller release than 1.2.0, but provides two useful changes.

First, I have now added support for axiom annotations as more extensively documented in my past post (http://www.russet.org.uk/blog/3028). While I expect these are still a minority requirement, they are used heavily by some people, and so they need supporting.

Second, I have reworked the support for patterns. This has been through the addition of three functions. p allows writing classes with optionality. So, for instance, consider this code:

(p o/owl-class
   o partition-name
   :comment comment
   :super super)

comment and super are optional here; they can be nil. In this case, the p function removes the nil value from the owl-class call. More over if, as in this case, the entire frame is has only nil values, it will be removed altogether. p returns the results of this call as a clojure record contain the entity itself and the name that was used to create that entity. In a nice piece of serendipity, the support that I have added for annotations (http://www.russet.org.uk/blog/3028), also allows direct use of this record latter in the pattern. So, for example, this form uses partition with is the return value from above.

(map
 #(p o/owl-class o
     %
     :comment comment
     :super partition)
   values)

The reason for this record, though, is that it makes it relatively easy to build patterns in both function and macro form. Macros are never trivial, but all this one does is turn a set of symbols into their string equivalents.

(defmacro defpartition
  "As value-partition but accepts symbols instead of string and
takes the ontology as a frame rather than first argument."
  [partition-name partition-values & options]
  (tawny.pattern/pattern-generator
   'tawny.pattern/value-partition
   (list* (name partition-name)
          `(tawny.util/quote-word ~@partition-values)
          options)))

The practical upshot of this is that I can define a value partition using a macro like this:

(defpartition Hydrophobicity
  [Hydrophobic Hydrophillic]
  :comment "Part of the Hydrophobicity value partition"
  :super PhysicoChemicalProperty
  :domain AminoAcid)

As well as generating the OWL API objects, this also binds the relevant vars, both those visible here (Hydrophobicity) and those generated (hasHydrophobicity).

Take together these are both important additions to Tawny-OWL. We can provide better provenance with the axiom annotations, and with patterns we can lift the level of abstraction at which we build our ontology which is one of the original motivations for Tawny-OWL in the first place.

Tawny-OWL 1.3.0 is now available on Clojars.

Bibliography

Since the early development of Tawny-OWL and easy to use syntax has been a specific objective (http://www.russet.org.uk/blog/2214), as well as hiding some of the complexity of the OWL API. The intension has always been for Tawny-OWL to be an ontology developer tool first and a programmatic library second and keeping this in mind has been part of the reason that I believe does fill these objectives.

Unfortunately, the other part of the reason is that Tawny-OWL does hides functionality that is available in the OWL API. Or, more strictly, does not uncover it. Tawny-OWL is implemented in Clojure and what is possible in Java is also possible in Java.

One of the key decisions was to hide the support that the OWL API provides for certain forms of annotation, in particular annotatons on axioms. Of course, Tawny-OWL allows you to add annotations to entities. This is used to enable labels and comments on any entity. But axiom annotations allow the description of the relationships between entities. So, for example, as well as attaching comments on two classes, it is also possible to attach a comment on the sub/superclass relatinship between the two.

The main reason that Tawny-OWL did not support these natively is that it takes an entity-centric view of OWL. So, if we consider this statement:

(defclass A
   :super B
   :label "A")

We are describing the entity A primarily. In fact, this statement translates into two axioms, which we can see in the OWL/XML representation which looks like this:

<SubClassOf>
    <Class IRI="#A"/>
    <Class IRI="#B"/>
</SubClassOf>
<AnnotationAssertion>
    <AnnotationProperty abbreviatedIRI="rdfs:label"/>
    <IRI>#A</IRI>
    <Literal xml:lang="en"
       datatypeIRI="http://www.w3.org/1999/02/22-rdf-syntax-ns#PlainLiteral">A</Literal>
</AnnotationAssertion>

The defclass statement above returns the entity (actually, the var as it is a def form, but the var contains the entity), rather than the axioms. If I wished to return the axioms, as there are several, I would need a list, or more probably, a data structure so that I could extract the axiom I wanted. This would, however, complicate life considerably. For instance, B would now refer to this data structure, which would need unpicking for its use here. Worse, the OWL API works by mutation, so the axioms in B might now reflect only some of the axioms refering to B.

Of course, there is a way around this, which is to dip down into the OWL API, fetching the axioms this way. As far as I can tell, annotations need to be added at the time the axiom is created (it is probably possible to do it later as well). This example comes from my recasting of the OWL Primer ontology.

(add-axiom
 (.getOWLSubClassOfAxiom (owl-data-factory)
  Man Person #{(owl-comment "States that every man is a person")}))

This works well, but the syntax is not nice, we need to do a direct call to the OWL API. We are not even using the add-subclass function. This did not bother my overly, as it was not something that I thought would be needed often.

Unfortunately, it is something that the Gene Ontology people do often, including, for instance, annotating labels with the source of knowledge for these labels. If I am to support them, I need an attractive syntax that fits with current Tawny-OWL syntax. After a couple of attempts, I decided on this:

(defclass A
  :super (annotate B
           (owl-comment "A is a kind of B")))

The axioms in Tawny-OWL are syntactically implicit, describing the :super relationship between A, so I cannot directly address these. But attaching an annotation to B in this way is unambiguous. Compare these two statements that it might otherwise be mistaken for; in one case, we annotate A with a comment (which is most common thing to do) or, we inline an annotation of B (which would probably be better not inline!).

(defclass A
  :super B
  :annotation (owl-comment "A is an interesting entity"))

(defclass A
  :super (owl-class B
            :annotation
               (owl-comment "B is an interesting entity")))

This also extends naturally to other axioms, including annotation labels.

(defclass A
  :annotation (annotate (label "A")
                 (owl-comment "According to me")))

The implementation of this took me several attempts, including some fairly painful and ultimately unsuccesful macros. In the end, I found a much simpler solution. annotate returns a clojure record which contains both the entity — (label "A") or B in these examples — and the annotation always an owl-comment here, but potentially anything. This record is passed through the Tawny-OWL function call stacks in place of the raw entity, until the appropriate axiom is created. I then unpick this object with two calls to protocol methods — as-entity and as-annotations like so.

(.getOWLAnnotationAssertionAxiom
    (owl-data-factory)
    (as-iri named-entity)
    ^OWLAnnotation (as-entity annotation)
    (as-annotations annotation)

The protocol implementations are trivial.

(defrecord Annotated [entity annotations]
  Entityable
  (as-entity [this] entity)
  Annotatable
  (as-annotations [this] annotations))

These allow me to avoid checking for an Annotated object when creating my axiom. In most cases, I will not have one of these, but a normal OWLObject. Or a Long, String or even a Keyword for property characteristics. So I extend the protocols to cover these cases also, with even more trivial implementations.

(extend-type
    Object
  Entityable
  (as-entity [entity] entity))

(extend-type
    Object
  Annotatable
  (as-annotations [entity]
    #{}))

Finally, the annotate function broadcasts as do many other functions in Tawny-OWL, so it is possible to annotate several axioms at once. So, for example, here explicitly using a list.

(defclass A
   :super (annotate [B C D]
             (owl-comment "All of these are supers")))

Or, implicitly with a function existential restriction that itself uses broadcasting.

(defclass A
   :super (annotate (owl-some r B C D)
             (owl-comment "All of these are existentials")))

While the syntax is slightly more complex than most of Tawny-OWL, it is a considerable improvement on dropping down to the OWL API layer beneath; and, ultimately, this form of annotation is a more complex usage of OWL.

Bibliography

About six months after the release of Tawny-OWL 1.1.0 (http://www.russet.org.uk/blog/2989), I am pleased to announce the 1.2 release. There have been a number of changes in this release, some planned, some not.

The planned changes have been an extension of the rendering capabilities of Tawny-OWL; it is now possible to render an OWLEntity entirely into Clojure data structures. The main reason for this was to allow use of core.logic for building an effective syntactic query language over OWL. This is now complete, although more work needs to be done on tawny.query if this is to be exploited to it’s fullest.

The main unplanned release was caused by a change in the OWL API which had dramatic (and negative) consequences for Tawny-OWL performance. The details of this change have been documented elsewhere (http://www.russet.org.uk/blog/3007). Fixing this actually resulted in small increases in rendering performance. This also lead me to some aggresive micro-optimisations of the Tawny-OWL code base, mostly meaning I can avoid using variadic function calls where necessary (these box arguments into a list, which can be quite slow). On small ontologies, Tawny-OWL will load several times faster now.

The pace of development on Tawny-OWL has slowed somewhat in recent times; partly, this is because it is now reaching a point of maturity. However, I have also been diverted by two other projects. I have put a reasonable amount of effort into Linked buffer which provides a rich literate environment, originally intended for Tawny-OWL, although it is not specific to it. And, secondly, I have started a manual for Tawny-OWL called Take Wing. This is developed using Linked Buffer. Not the first example of a literate program as a manual, I know, but probably the first example a literate ontology as a manual.

Despite the slowed pace, I have a roadmap for Tawny 1.3. I wish to support what I am calling transactional restrictions; these are a set of axioms which are either added all together or not at all. The use case for this comes from the Gene Ontology who use annotations on their annotations to describe evidence for particular statements. The meta annotations should not be added to the ontology, until the annotations are.

And secondly, I am reworking tawny.pattern — the existing value partition support has already been changed, and there are some new functions which make it easy to turn a functional pattern into a macro one; the latter produce the more attractive syntax.

No doubt there will be a few unplanned additions also!

Bibliography