// Create ontology OWLOntologyManager m = create(); OWLOntology o = m.createOntology(example_iri); // Add the OWL classes OWLClass nucleus = df.getOWLClass(IRI.create(example_iri + "#Nucleus")); OWLClass cell = df.getOWLClass(IRI.create(example_iri + "#Cell")); // Add the OWL object property OWLObjectProperty partOf = df.getOWLObjectProperty(IRI.create(example_iri + "#partOf")); // Assert the axiom // 1. Create the class expression OWLClassExpression partOfSomecell = df.getOWLObjectSomeValuesFrom(partOf, cell); // 2. Now create the axiom OWLAxiom axiom = df.getOWLSubClassOfAxiom(nucleus, partOfSomeCell); // 2. Add the axiom to the ontology AddAxiom addAxiom = new AddAxiom(o, axiom); // 3. We now use the manager to apply the change m.applyChange(addAxiom);
// Create ontology Brain brain = new Brain(); // Add the OWL classes brain.addClass("Nucleus"); brain.addClass("Cell"); // Add the OWL object property brain.addObjectProperty("partOf"); // Assert the axiom brain.subClassOf("Nucleus", "partOf some Cell");
(defontology o)
Class: o:A Annotations: rdfs:label "A"@en, rdfs:comment "A is a kind of thing."@en
(defclass A :label "A" :comment "A is a kind of thing.")
:frame-name and not frame-name:
:super rather that SubClassOf:
:super not SubPropertyOf:
:label and :comment
:sub meaning ontologies can be built bottom-up or top-down
(defclass B :super A :label "B")
> c(1,2,3) + 4 [1] 5 6 7
owl-some expand to two existential restrictions
(defoproperty r) (defclass C :super (owl-some r A B))
C some r A
C some r B
Class: o:C SubClassOf: o:r some o:B, o:r some o:A
some-only the most common
(defclass D :super (some-only r A B))
n+2) axioms
Class: o:D SubClassOf: o:r some o:A, o:r some o:B, o:r only (o:A or o:B)
(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)))
F has three subclasses
(defclass F :equivalent (owl-some r (owl-or A B))) ;; #{} (subclasses F) (reasoner-factory :hermit) ;; #{C D E} (isubclasses F)
git clone https://github.com/phillord/tawny-tutorial.git
_ in file name is - in namespace
:use makes tawny.owl namespace available
(ns tawny.tutorial.onto-hello (:use [tawny.owl]))
src/tawny/tutorial/onto_hello.clj
defontology statement
hello is a new variable
(defontology hello :iri "http://www.w3id.org/ontolink/tutorial/hello")
defclass statement
()
Hello is also a variable
Hello and hello are different
(defclass Hello)
defoproperty
o to distinguish annotation and datatype property
defclass and defoproperty take a number of frames
(defoproperty hasObject) (defclass World)
:super says "everything that follows is a super class"
HelloWorld has a :super which is Hello
owl-some is the existential operator
(defclass HelloWorld :super Hello (owl-some hasObject World))
owl-some rather than some
only and not owl-only
clojure.core
(owl-some hasObject World) (only hasObject World)
&&, || and !
owl-only)
tawny.english namespace
save-ontology
(save-ontology "o.omn" :omn)
refine
defclass form and re-evaluate
:label and :comment add annotations using OWL built-in
:annotation is general purpose frame
(refine HelloWorld :label "Hello World" :comment "Hello World is a kind of greeting directed generally at everything." :annotation (label "Aalreet world" "gb_ncl"))
(ns tawny.tutorial.amino-acid-tree (:use [tawny.owl]))
src/tawny/tutorial/amino_acid_tree.clj
(defontology aa) (defclass AminoAcid) (defclass Alanine :super AminoAcid) (defclass Arginine :super AminoAcid) (defclass Asparagine :super AminoAcid) ;; and the rest...
Asparagine is not the same as Alanine or Arginine
(defclass Asparagine :super AminoAcid :disjoint Alanine Arginine)
Arginine to this
(defclass Arginine :super AminoAcid :disjoint Alanine Asparagine)
as-subclasses form
AminoAcid as super to all arguments
(defclass AminoAcid) (as-subclasses AminoAcid (defclass Alanine) (defclass Arginine) (defclass Asparagine) ;; and the rest... )
:disjoint keyword
(defclass AminoAcid) (as-subclasses AminoAcid :disjoint (defclass Alanine) (defclass Arginine) (defclass Asparagine) ;; and the rest... )
(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))
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
:use clause means "use both tawny.owl and tawny.pattern"
(ns tawny.tutorial.amino-acid-props (:use [tawny owl pattern]))
src/tawny/tutorial/amino_acid_props.clj
(defontology aa) (defclass AminoAcid)
AminoAcid's have a size, and only one size!
(defclass Size) (defoproperty hasSize :domain AminoAcid :range Size :characteristic :functional)
(as-subclasses Size :disjoint :cover (defclass Tiny) (defclass Small) (defclass Large))
(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))) ;;and the rest
Charge using the same pattern as Size
(defclass Charge) (defoproperty hasCharge :domain AminoAcid :range Charge :characteristic :functional) (as-subclasses Charge :disjoint :cover (defclass Positive) (defclass Neutral) (defclass Negative))
hasCharge
(as-facet hasCharge Positive Neutral Negative)
refine although could just alter the code
(facet Neutral) rather than (owl-some hasCharge Neutral)
(refine Alanine :super (facet Neutral)) (refine Arginine :super (facet Positive)) (refine Asparagine :super (facet Neutral))
as-facet declaration
Hydrophobicity
(defclass Hydrophobicity) (defoproperty hasHydrophobicity :domain AminoAcid :range Hydrophobicity :characteristic :functional) (as-subclasses Hydrophobicity :disjoint :cover (defclass Hydrophobic) (defclass Hydrophilic)) (as-facet hasHydrophobicity Hydrophilic Hydrophobic)
Polarity.
(defclass Polarity) (defoproperty hasPolarity) (as-subclasses Polarity :disjoint :cover (defclass Polar) (defclass NonPolar)) (as-facet hasPolarity Polar NonPolar)
facet broadcasts
(refine Alanine :super (facet Hydrophobic NonPolar)) (refine Arginine :super (facet Hydrophilic Polar)) (refine Asparagine :super (facet Hydrophilic Polar))
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
Polarity)
tawny.pattern
use it here
(ns tawny.tutorial.amino-acid-pattern (:use [tawny owl pattern]))
src/tawny/tutorial/amino_acid_pattern.clj
(defontology aa) (defclass AminoAcid)
Size value partitiondefpartition defines that we will have a partition
[Tiny Small Large] are the values
hasSize is implicit — it will be created
(defpartition Size [Tiny Small Large] :domain AminoAcid)
ObjectProperty: aa:hasSize Domain: aa:AminoAcid Range: aa:Size Characteristics: Functional Class: aa:Size EquivalentTo: aa:Large or aa:Small or aa:Tiny
(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)
defpartition also applies the as-facet function
facet also
(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)) ;; and the rest )
tawny.obo to support (OBO) numeric IDs
clojure.string is for string manipulation
(ns tawny.tutorial.whats-in-a-name (:use [tawny.owl]) (:require [tawny.obo]) (:require [clojure.string :as s]))
A rather than "A")
(defontology o) ;; => #<OWLClassImpl <8d9d3120-d374-4ffb-99d8-ffd93a7d5fdd#o#A>> (defclass A :ontology o)
:ontology frame
:iri frame for our second ontology
(defontology i :iri "http://www.w3id.org/ontolink/example/i") ;; => #<OWLClassImpl <http://www.w3id.org/ontolink/example/i#B>> (defclass B :ontology i)
:iri-gen frame to supply a function
(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)
(defclass GO:00004324 :super (owl-some RO:0000013 GO:00003143) :annotation (annotation IAO:0504303 "Transporters are..."))
(defontology obo :iri "http://www.w3id.org/ontolink/example/obo" :iri-gen tawny.obo/obo-iri-generate) (tawny.obo/obo-restore-iri obo "./src/tawny/tutorial/whats_in_a_name.edn")
;; => #<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)
(ns tawny.tutorial.abc (:use [tawny.owl])) (defontology abc :iri "http://www.w3id.org/ontolink/example/abc.owl") (defclass A) (defclass B) (defclass C)
use many times before
require
(ns tawny.tutorial.use-abc (:use [tawny.owl]) (:require [tawny.tutorial.abc]))
owl-import will its axioms become available
import function and it does not do
the same thing
(defontology myABC) (owl-import tawny.tutorial.abc/abc)
abc ontology
require statement also allows us to use symbols
tawny.tutorial.abc
A
(defclass MyA :super tawny.tutorial.abc/A) (defclass MyB :super tawny.tutorial.abc/B)
Class: myABC:MyA SubClassOf: abc:A Class: myABC:MyB SubClassOf: abc:B
require or use is a part of Clojure
owl-import
Require the tawny.owl and tawny.read
(ns tawny.tutorial.read-abc (:require [tawny owl read]))
(tawny.read/defread abc :iri "http://www.w3id.org/ontolink/example/abcother.owl" :location (tawny.owl/iri (clojure.java.io/resource "abcother.owl")))
abcother.owl has been saved locally
abc ontology
(tawny.owl/defontology myABC) (tawny.owl/owl-import abc)
(tawny.owl/defclass MyA :super A) (tawny.owl/defclass MyB :super B)
(ns tawny.tutorial.amino-acid-build (:use [tawny owl pattern reasoner util]))
(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)
amino-acidamino-aciddefdontfn gives default ontology handling
amino-acid
& properties is variadic or "one or more args".
owl-class function does not define a new symbol
(defdontfn amino-acid [o entity & properties] (owl-class o entity :super (facet properties)))
amino-acidsamino-acid at once
map
->Named packages name and entity together
(defdontfn amino-acids [o & definitions] (map (fn [[entity & properties]] ;; need the "Named" constructor here (->Named entity (amino-acid o entity properties))) definitions))
(defmacro defaminoacids [& definitions] `(tawny.pattern/intern-owl-entities (apply amino-acids (tawny.util/name-tree ~definitions))))
:cover
(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]))
Small facet is a SmallAminoAcid
(defclass SmallAminoAcid :equivalent (facet Small))
(defclass SmallPolarAminoAcid :equivalent (owl-and (facet Small Polar))) (defclass LargeNonPolarAminoAcid :equivalent (owl-and (facet Large NonPolar)))
(defn amino-acid-def [partition-values] (owl-class (str (clojure.string/join (map #(.getFragment (.getIRI %)) partition-values)) "AminoAcid") :equivalent (owl-and (facet partition-values))))
amino-acid-def function on the Cartesian product
(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))))))))
(reasoner-factory :hermit) ;; => true (consistent?)
AminoAcid
;; => 20 (count (subclasses AminoAcid)) ;; => 451 (count (isubclasses AminoAcid))
;; => false (coherent?) ;; => 242 (count (unsatisfiable))
(save-ontology "aabuild.owl" :owl)
Negative and Hydrophobic)
;; => 242 (count (isubclasses SmallAminoAcid))
;; => 0 (count (filter #(not (.isDefined % aabuild)) (isubclasses SmallAminoAcid)))
:super? why not :subclass?
function?
SubClassOf axiom between Man and Person with a comment.
(defclass Man :super (annotate Person (owl-comment "States that every man is a person")))
(label "Ciao" "it")
(defn etichetta [l] (label l "it"))
tawny.polyglot to use property bundles
tawny.memorize to remember mappings
tawny.render can perform a syntactic transformation
:super? why not :subclass?SubClassOf:
:super for the same purpose!
A has :frame B
A is a SubClassOf: B
obo-restore-iri line above reads this file
("ro" "http://purl.obolibrary.org/obo/EXAM_000001" "G" "http://purl.obolibrary.org/obo/EXAM_000002" "F" "http://purl.obolibrary.org/obo/EXAM_000003")
this stores any new IDs we have created (comment (tawny.obo/obo-store-iri obo "./src/tawny/tutorial/whats_in_a_name.edn"))
this coins permanent IDS, in a controlled process! (comment (tawny.obo/obo-generate-permanent-iri "./src/tawny/tutorial/whats_in_a_name.edn" "http://purl.obolibrary.org/obo/EXAM_"))
iri-gen function takes a string not a symbol!
String building! (defontology s) (owl-class "J" :ontology s) (object-property "r" :ontology s) (owl-class "K" :ontology s :super (owl-some "r" "J"))
r nor J have been defined
(comment (owl-class "L" :ontology s :super (owl-some r J)))
(owl-class "M" :ontology s :super "L")
Class: s:M SubClassOf: s:L Class: s:L
amino-acid syntax?defentity
(defentity defaminoacid "Defines a new amino acid." 'amino-acid)
tawny.owl through an alias
(ns tawny.tutorial.autosave (:require [tawny.owl :as o]) (:import [org.semanticweb.owlapi.model.OWLOntologyChangeListener]))
atom and change that
(def auto-save-listener "The current listener for handling auto-saves or nil." (atom nil))
(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)))
o, filename, format are closed over
(proxy [org.semanticweb.owlapi.model.OWLOntologyChangeListener] [] (ontologiesChanged[l] (o/save-ontology o filename format)))
(reset! auto-save-listener listener)
o/owl-ontology-manager function returns an OWLOntologyManager
. syntax to call methods
addOntologyChangeListener on the manager
listener as an argument
(.addOntologyChangeListener (o/owl-ontology-manager) listener)
@ dereferences the atom
(defn auto-save-off "Stop autosaving ontologies." [] (when @auto-save-listener (.removeOntologyChangeListener (o/owl-ontology-manager) @auto-save-listener)))
auto-save function in tawny.repl
on-change function