Introduction

Today

Today

Knowledge Prerequisites

Outcomes

Secondary Outcomes

Notes on Notes

Motivation

Use Case (chromosomes)

ChromXISCN09.jpg

Use Case (karyotypes)

A partonomy?

ChromXISCN09.jpg

Protege

protege-pizza.png

Protege

click.gif

Protege

click-fast.gif

Can we do this programmatically?

OWLClass clsA = df.getOWLClass(IRI.create(pizza_iri + "#A"));
OWLClass clsB = df.getOWLClass(IRI.create(pizza_iri + "#B"));
// Now create the axiom
OWLAxiom axiom = df.getOWLSubClassOfAxiom(clsA, clsB);
// add the axiom to the ontology.
AddAxiom addAxiom = new AddAxiom(o, axiom);
// We now use the manager to apply the change
m.applyChange(addAxiom);

Brain

Brain brain = new Brain();
//Add the OWL classes
brain.addClass("Nucleus");
brain.addClass("Cell");
//Add the OWL object property
brain.addObjectProperty("part-of");
//Assert the axiom
brain.subClassOf("Nucleus", "part-of some Cell");

The Paragon

Constraints

Karyotype Ontology

Tawny-OWL Key Features

Ontology Building Tool

Unprogrammatic Syntax

(defontology o)

Unprogrammatic Syntax

Class: o:A

    Annotations:
        rdfs:label "A"@en,
        rdfs:comment "A is a kind of thing."@en

Unprogrammatic Syntax

(defclass A
  :label "A"
  :comment "A is a kind of thing.")

Unprogrammatic Syntax

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

Unprogrammatic Syntax

Evaluative

Compiled

Broadcasting

> c(1,2,3) + 4
[1] 5 6 7

Broadcasting

(defoproperty r)
(defclass C
  :super (owl-some r A B))
Class: o:C
    SubClassOf:
        o:r some o:B,
        o:r some o:A

Patternized

(defclass D
  :super (some-only r A B))
Class: o:D

    SubClassOf:
        o:r some o:A,
        o:r some o:B,
        o:r only
            (o:A or o:B)

Single syntax Extensible

(defn and-not [a b]
  (owl-and a (owl-not b)))

(defn some-and-not [r a b]
  (owl-some r (and-not a b)))

(defclass E
  :super (some-and-not r A B))
Class: o:E
    SubClassOf:
        o:r some
            (o:A or (not (o:B)))

Reasoned Over

(defclass F
   :equivalent (owl-some r (owl-or A B)))

;; #{}
(subclasses F)

(reasoner-factory :hermit)

;; #{C D E}
(isubclasses F)

Commodity Language

Commodity Toolchain

Tawny Tutorial

Other Technical Pre-Requisites

Installing JVM

Installing Leiningen

Testing the Pre-Requisities

lein run

The Tawny Tutorial is Installed and Ready

Protege

Or: the alternative

Paying the Piper

Clojure environments

Catnip

Catnip

lein edit

Catnip running on http://localhost:nnnn

Catnip

(ns lisbon.hello)

(def hello "hello world")

What have we achieved

Task 1

Build a Hello World Ontology!

Ontological Hello World

Ontological Hello World

The namespace

(ns lisbon.onto-hello
  (:use [tawny.owl]))

Define an Ontology

(defontology hello
  :iri "http://www.w3id.org/ontolink/tutorial/hello")

Introduce a Class

(defclass Hello)

Properties

(defoproperty hasObject)
(defclass World)

A complex class

(defclass HelloWorld
  :super Hello
  (owl-some hasObject World))

On the use of "owl" (a quick diversion)

(owl-some hasObject World)
(only hasObject World)

On the use of "owl"

On the use of "owl"

Save the Ontology

(save-ontology "o.omn" :omn)

More Frames

(refine HelloWorld
        :label "Hello World"
        :comment "Hello World is a kind of greeting directed generally at everything."
        :annotation (label "Olá mundo" "pt"))

Task 1: Conclusions

Task 2: Defining a Tree

Amino Acids

A namespace

(ns lisbon.amino-acid-tree
  (:use [tawny.owl]))

Tree

(defontology aa)

(defclass AminoAcid)

(defclass Alanine
          :super AminoAcid)

(defclass Arginine
          :super AminoAcid)

(defclass Asparagine
          :super AminoAcid)

;; and the rest...

Disjoint

(defclass Alanine
    :super AminoAcid
    :disjoint Arginine Asparagine)

Disjoint

(defclass Arginine
    :super AminoAcid
    :disjoint Alanine Asparagine)

Explict Definition

Simplifying the definition

(defclass AminoAcid)

(as-subclasses
  AminoAcid

  (defclass Alanine)
  (defclass Arginine)
  (defclass Asparagine)
  ;; and the rest...
  )

And disjoint!

(defclass AminoAcid)

(as-subclasses
 AminoAcid
 :disjoint

 (defclass Alanine)

 (defclass Arginine)

 (defclass Asparagine)

 ;; and the rest...
 )

And, finally, covering

And, finally, covering

(defclass AminoAcid)

(as-subclasses
 AminoAcid
 :disjoint :cover

 (defclass Alanine)
 (defclass Arginine)
 (defclass Asparagine)
 (defclass Aspartate)
 (defclass Cysteine)
 (defclass Glutamate)
 (defclass Glutamine)
 (defclass Glycine)
 (defclass Histidine)
 (defclass Isoleucine)
 (defclass Leucine)
 (defclass Lysine)
 (defclass Methionine)
 (defclass Phenylalanine)
 (defclass Proline)
 (defclass Serine)
 (defclass Threonine)
 (defclass Tryptophan)
 (defclass Tyrosine)
 (defclass Valine))

And, finally, covering

Class: aa:AminoAcid
    EquivalentTo:
        aa:Alanine or aa:Arginine or aa:Asparagine
        or aa:Aspartate or aa:Cysteine or aa:Glutamate
        or aa:Glutamine or aa:Glycine or aa:Histidine
        or aa:Isoleucine or aa:Leucine or aa:Lysine
        or aa:Methionine or aa:Phenylalanine or aa:Proline
        or aa:Serine or aa:Threonine or aa:Tryptophan
        or aa:Tyrosine or aa:Valine

DisjointClasses:
    aa:Alanine, aa:Arginine, aa:Asparagine, aa:Aspartate,
    aa:Cysteine, aa:Glutamate, aa:Glutamine, aa:Glycine,
    aa:Histidine, aa:Isoleucine, aa:Leucine, aa:Lysine,
    aa:Methionine, aa:Phenylalanine, aa:Proline, aa:Serine,
    aa:Threonine, aa:Tryptophan, aa:Tyrosine, aa:Valine

Task 2: Conclusions

Task 3 — Defining some properties

Namespace

(ns lisbon.amino-acid-props
  (:use [tawny owl pattern]))

Starting our ontology

(defontology aa)

(defclass AminoAcid)

Amino Acid properties

The Value Paritition

(defclass Size)
(defoproperty hasSize
  :domain AminoAcid
  :range Size
  :characteristic :functional)

Value Partition

(as-subclasses
 Size
 :disjoint :cover

 (defclass Tiny)
 (defclass Small)
 (defclass Large))

Using the values


(as-subclasses
 AminoAcid
 :disjoint :cover

 (defclass Alanine
   :super (owl-some hasSize Tiny))

 (defclass Arginine
   :super (owl-some hasSize Large))

 (defclass Asparagine
   :super (owl-some hasSize Small)))

Using Facets

(defclass Charge)
(defoproperty hasCharge
  :domain AminoAcid
  :range Charge
  :characteristic :functional)

(as-subclasses
 Charge
 :disjoint :cover

 (defclass Positive)
 (defclass Neutral)
 (defclass Negative))

Facet

(as-facet
 hasCharge

 Positive Neutral Negative)

Using the facet


(refine Alanine
        :super (facet Neutral))

(refine Arginine
         :super (facet Positive))

(refine Asparagine
        :super (facet Neutral))

And others

(defclass Hydrophobicity)
(defoproperty hasHydrophobicity
  :domain AminoAcid
  :range Hydrophobicity
  :characteristic :functional)

(as-subclasses
 Hydrophobicity
 :disjoint :cover

 (defclass Hydrophobic)
 (defclass Hydrophilic))

(as-facet
 hasHydrophobicity

 Hydrophilic Hydrophobic)

Using Facets

(defclass Polarity)
(defoproperty hasPolarity)

(as-subclasses
 Polarity
 :disjoint :cover

 (defclass Polar)
 (defclass NonPolar))

(as-facet
 hasPolarity

 Polar NonPolar)

Using Facets

(refine
 Alanine
 :super (facet Hydrophobic NonPolar))

(refine
 Arginine
 :super (facet Hydrophilic Polar))

(refine
 Asparagine
 :super (facet Hydrophilic Polar))

Using Facets

Class: aa:Alanine

    SubClassOf:
        aa:hasCharge some aa:Neutral,
        aa:AminoAcid,
        aa:hasSize some aa:Tiny,
        aa:hasHydrophobicity some aa:Hydrophobic,
        aa:hasPolarity some aa:NonPolar

Task 3: Conclusions

Task 4 Patternising

Patternising

Namespace

(ns lisbon.amino-acid-pattern
  (:use [tawny owl pattern]))

And the preamble

(defontology aa)

(defclass AminoAcid)

The size value partition

(defpartition Size
  [Tiny Small Large]
  :domain AminoAcid)

The size value partition

ObjectProperty: aa:hasSize
    Domain:
        aa:AminoAcid

    Range:
        aa:Size

    Characteristics:
        Functional


Class: aa:Size
    EquivalentTo:
        aa:Large or aa:Small or aa:Tiny

More value partitions

(defpartition Charge
  [Positive Neutral Negative]
  :domain AminoAcid)

(defpartition Hydrophobicity
  [Hydrophobic Hydrophilic]
  :domain AminoAcid)

(defpartition Polarity
  [Polar NonPolar]
  :domain AminoAcid)

(defpartition SideChainStructure
  [Aromatic Aliphatic]
  :domain AminoAcid)

Using these partitions

(as-subclasses
 AminoAcid

 (defclass Alanine
   :super (facet Neutral Hydrophobic NonPolar Aliphatic Tiny))

 (defclass Arginine
   :super (facet Positive Hydrophilic Polar Aliphatic Large))

 (defclass Asparagine
   :super (facet Neutral Hydrophilic Polar Aliphatic Small))

 (defclass Aspartate
   :super (facet Negative Hydrophilic Polar Aliphatic Small))

 ;; and the rest
 )

Task 4: Patternising

Task 5: Understanding Names

Background

OWL

Symbols

Namespace

(ns lisbon.whats-in-a-name
  (:use [tawny owl obo])
  (:require [clojure.string :as s))

Symbols and IRIs

(defontology o)

;; => #<OWLClassImpl <8d9d3120-d374-4ffb-99d8-ffd93a7d5fdd#o#A>>
(defclass A
  :ontology o)

Symbols and IRIs

(defontology i
   :iri "http://www.w3id.org/ontolink/example/i")

;; => #<OWLClassImpl <http://www.w3id.org/ontolink/example/i#B>>
(defclass B
  :ontology i)

Symbols and IRIs

(defontology r
  :iri "http://www.w3id.org/ontolink/example/r"
  :iri-gen (fn [ont name]
             (iri (str (as-iri ont)
                       "#"
                       (s/reverse name)))))

;; => #<OWLClassImpl <http://www.w3id.org/ontolink/example/r#EDC>>
(defclass CDE
  :ontology r)

The iri-gen function

(fn [ont name]          ;; <1>
  (iri                  ;; <2>
   (str                 ;; <3>
    (as-iri ont)        ;; <4>
    "#"                 ;; <5>
    (s/reverse name)))) ;; <6>

This is the first function we have seen so, we go through it in detail

  1. Create an anonymous function, with parameters ont and name

  2. Create an IRI object from the string

  3. Concatentate all arguments

  4. Get the Ontology IRI

  5. "#"

  6. Reverse the name passed in!

OBO identifiers

(defclass GO:00004324
  :super (owl-some RO:0000013 GO:00003143)
  :annotation (annotation IAO:0504303 "Transporters are..."))

OBO Identifiers

(defontology obo
  :iri "http://www.w3id.org/ontolink/example/obo"
  :iri-gen tawny.obo/obo-iri-generate)
(tawny.obo/obo-restore-iri obo "./src/lisbon/whats_in_a_name.edn")

OBO Identifiers

;; => #<OWLClassImpl <http://purl.obolibrary.org/obo/EXAM_000003>>
(defclass F
  :ontology obo)

;; => #<OWLClassImpl <http://purl.obolibrary.org/obo/EXAM_000002>>
(defclass G
  :ontology obo)

;; => #<OWLObjectPropertyImpl <http://purl.obolibrary.org/obo/EXAM_000001>>
(defoproperty ro
  :ontology obo)

OBO Identifiers

;; => #<OWLClassImpl <http://purl.org/ontolink/preiri/#4b463bc1-414b-4730-89a3-7ff72902c744>>
(defclass H
  :ontology obo)

How OBO Identifiers work

How OBO Identifiers work

("ro"
 "http://purl.obolibrary.org/obo/EXAM_000001"
 "G"
 "http://purl.obolibrary.org/obo/EXAM_000002"
 "F"
 "http://purl.obolibrary.org/obo/EXAM_000003")

How OBO identifiers

;; this stores any new IDs we have created
(comment
  (tawny.obo/obo-store-iri obo "./src/lisbon/whats_in_a_name.edn"))

How OBO Identifers work

;; this coins permanent IDS, in a controlled process!
(comment
  (tawny.obo/obo-generate-permanent-iri
   "./src/lisbon/whats_in_a_name.edn"
   "http://purl.obolibrary.org/obo/EXAM_"))

How OBO Identifiers work

Tawny Names

;; String building!
(defontology s)

(owl-class "J" :ontology s)
(object-property "r" :ontology s)
(owl-class "K"
           :ontology s
           :super (owl-some "r" "J"))

Tawny Name

(comment
  (owl-class "L"
             :ontology s
             :super (owl-some r J)))

Tawny Name

(owl-class "M"
           :ontology s
           :super "L")
Class: s:M
    SubClassOf:
        s:L

Class: s:L

Why use strings?

Summary

tawny-name.png

Task 5: Conclusions

Task 6: Importing Other Ontologies

Importing

J’accuse reuse

An ontology to import

(ns lisbon.abc
  (:use [tawny.owl]))

(defontology abc
  :iri "http://www.w3id.org/ontolink/example/abc.owl")

(defclass A)
(defclass B)
(defclass C)

Using this ontology

Using

(ns lisbon.use-abc
  (:use [tawny.owl])
  (:require [lisbon.abc]))

Using

(defontology useabc)

(owl-import lisbon.abc/abc)

Using

(defclass MyA
  :super (iri "http://www.w3id.org/ontolink/example/abc.owl#A"))

Using

(defclass MyB
  :super lisbon.abc/B)

Using

Class: useabc:MyA
    SubClassOf:
        abc:A

Class: useabc:MyB
    SubClassOf:
        abc:B

Task 6: Summary

Task 7: Reading an Ontology

The problem

Namespace

(ns lisbon.read-abc-s
  (:use [tawny.owl])
  (:require [tawny.read]))

Solution 1

Solution 2

(tawny.read/defread abc
  :iri "http://www.w3id.org/ontolink/example/abcother.owl"
  :location (tawny.owl/iri (clojure.java.io/resource "abcother.owl")))

Reading

(defontology myABC)

(owl-import abc)

Reading

(defclass MyA
  :super A)

(defclass MyB
  :super B)

Task 7: Conclusion

Task 8: Programming an Autosave

Extending Tawny

Namespace

(ns lisbon.autosave
  (:require [tawny.owl :as o])
  (:import [org.semanticweb.owlapi.model.OWLOntologyChangeListener]))

Saving the Listener

(def auto-save-listener
  "The current listener for handling auto-saves or nil." (atom nil))

The auto-save function

(defn auto-save
  "Autosave the current ontology everytime any change happens."
  ([o filename format]
   (let [listener (proxy [org.semanticweb.owlapi.model.OWLOntologyChangeListener]
               []
             (ontologiesChanged[l]
               (o/save-ontology o filename format)))]
     (reset! auto-save-listener listener)
     (.addOntologyChangeListener
      (o/owl-ontology-manager) listener)
     listener)))

auto-save in detail

(proxy [org.semanticweb.owlapi.model.OWLOntologyChangeListener]
       []
   (ontologiesChanged[l]
      (o/save-ontology o filename format)))

auto-save in detail

   (reset! auto-save-listener listener)

auto-save in detail

(.addOntologyChangeListener
     (o/owl-ontology-manager) listener)

Remove the auto-save

(defn auto-save-off
  "Stop autosaving ontologies."
  []
  (when @auto-save-listener
    (.removeOntologyChangeListener
     (o/owl-ontology-manager)
     @auto-save-listener)))

auto-save

Task 8: Conclusion

Task 9: Create New Syntax

The Finale

The namespace

(ns lisbon.amino-acid-build
  (:use [tawny owl pattern reasoner util]))

The Upper Ontology

(defontology aabuild)

(defclass AminoAcid)

(defclass PhysicoChemicalProperty)

(defpartition Size
  [Tiny Small Large]
  :domain AminoAcid
  :super PhysicoChemicalProperty)

(defpartition Charge
  [Positive Neutral Negative]
  :domain AminoAcid
  :super PhysicoChemicalProperty)

(defpartition Hydrophobicity
  [Hydrophobic Hydrophilic]
  :domain AminoAcid
  :super PhysicoChemicalProperty)

(defpartition Polarity
  [Polar NonPolar]
  :domain AminoAcid
  :super PhysicoChemicalProperty)

(defpartition SideChainStructure
  [Aromatic Aliphatic]
  :domain AminoAcid
  :super PhysicoChemicalProperty)

Defining our AminoAcids

Defining out AminoAcid

(defdontfn amino-acid [o entity & properties]
  (owl-class o entity
     :super
     (facet properties)))

Making a new variable

(defentity defaminoacid
  "Defines a new amino acid."
  'amino-acid)

Define Lots of Amino Acids

(defdontfn amino-acids [o & definitions]
  (map
   (fn [[entity & properties]]
     ;; need the "Named" constructor here
     (->Named entity
              (amino-acid o entity properties)))
   definitions))

And make variables

(defmacro defaminoacids
  [& definitions]
  `(tawny.pattern/intern-owl-entities
    (apply amino-acids
     (tawny.util/name-tree ~definitions))))

Define the amino-acids

(as-subclasses
 AminoAcid
 :disjoint :cover

 (defaminoacids
   [Alanine        Neutral  Hydrophobic NonPolar Aliphatic Tiny]
   [Arginine       Positive Hydrophilic Polar    Aliphatic Large]
   [Asparagine     Neutral  Hydrophilic Polar    Aliphatic Small]
   [Aspartate      Negative Hydrophilic Polar    Aliphatic Small]
   [Cysteine       Neutral  Hydrophobic Polar    Aliphatic Small]
   [Glutamate      Negative Hydrophilic Polar    Aliphatic Small]
   [Glutamine      Neutral  Hydrophilic Polar    Aliphatic Large]
   [Glycine        Neutral  Hydrophobic NonPolar Aliphatic Tiny]
   [Histidine      Positive Hydrophilic Polar    Aromatic  Large]
   [Isoleucine     Neutral  Hydrophobic NonPolar Aliphatic Large]
   [Leucine        Neutral  Hydrophobic NonPolar Aliphatic Large]
   [Lysine         Positive Hydrophilic Polar    Aliphatic Large]
   [Methionine     Neutral  Hydrophobic NonPolar Aliphatic Large]
   [Phenylalanine  Neutral  Hydrophobic NonPolar Aromatic  Large]
   [Proline        Neutral  Hydrophobic NonPolar Aliphatic Small]
   [Serine         Neutral  Hydrophilic Polar    Aliphatic Tiny]
   [Threonine      Neutral  Hydrophilic Polar    Aliphatic Tiny]
   [Tryptophan     Neutral  Hydrophobic NonPolar Aromatic  Large]
   [Tyrosine       Neutral  Hydrophobic Polar    Aromatic  Large]
   [Valine         Neutral  Hydrophobic NonPolar Aliphatic Small]))

Defined Classes

(defclass SmallAminoAcid
  :equivalent (facet Small))

And some more

(defclass
  SmallPolarAminoAcid
  :equivalent (owl-and (facet Small Polar)))

(defclass LargeNonPolarAminoAcid
  :equivalent (owl-and (facet Large NonPolar)))

Where to stop

A defined class function

(defn amino-acid-def [partition-values]
  (owl-class
   (str
    (clojure.string/join
     (map
      #(.getFragment
        (.getIRI %))
      partition-values))
    "AminoAcid")
   :equivalent (owl-and (facet partition-values))))

Doing them all

(defn cart [colls]
  (if (empty? colls)
    '(())
    (for [x (first colls)
          more (cart (rest colls))]
      (cons x more))))

Doing them all

(doall
 (map
  amino-acid-def
  ;; kill the empty list
  (rest
   (map
    #(filter identity %)
    ;; combination of all of them
    (cart
     ;; list of values for each partitions plus nil
     ;; (so we get shorter versions also!)
     (map
      #(cons nil (seq (direct-subclasses %)))
      ;; all our partitions
      (seq (direct-subclasses PhysicoChemicalProperty))))))))

Reasoning

(reasoner-factory :hermit)
(consistent?)

Reasoning

(count (subclasses AminoAcid))
(count (isubclasses AminoAcid))

Reasoning

(coherent?)

(count (unsatisfiable))

Visualising

(save-ontology "o.owl" :owl)

Visualising

As a query

(count
 (isubclasses SmallAminoAcid))

As a query

(count
 (filter
  #(not (.isDefined % aabuild))
  (isubclasses SmallAminoAcid)))

Conclusions

Hiatus

Questions and Answers

Questions

Can I add annotations on axioms?

(defclass Man
 :super
 (annotate Person
           (owl-comment "States that every man is a person")))

How does this affect ontology deployment

How do you version your ontology?

How do you test your ontology

How do you continuously integrate your ontology?

What about advanced documentation for Ontologies?

How do I collaborative develop by ontology?

Can I internationalise my ontology?

(label "Ciao" "it")
(defn etichetta [l]
  (label l "it"))

Can I scaffold my ontology from existing source

What happens if the labels of read ontologies change

How do you convert an existing ontology to Tawny

How Fast is Tawny

Can I integrate more tightly with protege?

How does Tawny affect dependency management with ontologies?

Can I link ontologies into software?

What’s this :super? why not :subclass?

Conclusions

Acknowledgements