// 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-acid
amino-acid
defdontfn
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-acids
amino-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