<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>A Functional API for OWL</article-title>
      </title-group>
      <contrib-group>
        <aff id="aff0">
          <label>0</label>
          <institution>Data Semantics Lab, Kansas State University</institution>
          ,
          <country country="US">USA</country>
        </aff>
      </contrib-group>
      <abstract>
        <p>We present (f OWL), a minimalistic, functional programming style ontology editor that is based directly on the OWL 2 Structural Speci cation. (f OWL) is written from scratch, entirely in Clojure, having no other dependencies. Ontologies in (f OWL) are implemented as standalone and homogeneous data structures, which means that the same exact functions written for single axioms or expressions often work identically on any part of an ontology, even the entire ontology itself. The lazy functional style of Clojure also allows for intuitive and simple ontology creation and modi cation with a minimal memory footprint. All of this is possible without ever needing to use a single class, except of course in the Ontologies one creates! The semantic web community has widely adopted the OWL API [2] for ontology creation and development. Many researchers and programmers nd this software very useful and enjoy its Object-Oriented style. Other APIs for OWL have also been written in imperative languages like Owlready [3] in Python. However, some developers prefer to program in functional languages and nd that the imperative style APIs are more of a hindrance than a help when dealing with ontologies. There has been work towards providing functional style programming for OWL, like Tawny-OWL [4], but this is fundamentally dependent on the OWL API so it is cosmetically functional but not obviously compatible with many of the unique features and optimizations of the functional style. In order to support other styles of programming for ontologies we have developed (f OWL), a functional perspective on ontology development.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>Motivation</title>
      <p>(f OWL)
As an original standalone piece of software, (f OWL) is not a wrapper for the
OWL API. It starts again at the beginning and is truly functional from the
ground up. (f OWL) was written with Clojure because it is a functional
language that compiles with the Java Virtual Machine, and thus will have a broad
compatibility with any machine that can run Java. Clojure has the added bene t</p>
      <p>
        Functional Lisp-like syntax
No dependencies Requires only Clojure
No classes Objects can be created and manipulated directly
Ontology data structure Homogeneous and uniform: can be traversed
Lightweight Supports OWL 2, no unnecessary baggage
Clojure E ciency Lazy functions and optimizable recursion
Concise function names Avoids verbose unhelpful Java conventions
of intuitive native laziness, so writing e cient programs to create and
manipulate ontologies is not a challenge. To ensure that the semantics are correct, (f
OWL) directly implements the grammar of the OWL 2 Structural Speci cation
[
        <xref ref-type="bibr" rid="ref5">5</xref>
        ]. And because it is entirely original, (f OWL) is divorced from any historical
dependencies and commitments that clutter other software.
      </p>
      <p>(f OWL) includes many novel optimizations that streamline ontology
development. True to the functional paradigm (f OWL) uses functions and shuns
classes. Indeed all OWL ontology objects can be created directly with (f OWL)
functions. And since these functions are not bound up in an arbitrary class
hierarchy, they can operate on independent data structures that are internally typed
to represent OWL semantics. A (f OWL) ontology itself is simply another data
structure made of collections of smaller similar structures. This means that in
most cases an expression, an axiom, even an ontology can be traversed
recursively as-is without writing more functions. (f OWL) also simpli es many of the
unhelpful, highly verbose Java-style function names that occur in other programs
and instead adopts a concise functional naming scheme.</p>
      <p>
        (f OWL) is built and tested using Leiningen1 and the source code can be
found on GitHub.2 During testing, it e ciently reads and writes copies of over
260 di erent functional syntax ontologies from various domains, including the
massive Gene ontology [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ], with no errors being detected. It is available on the
Clojars3 repository so that users can easily import it into their own Clojure
projects. ClojureDoc4 for (f OWL) is available, and documentation is also
accessible in the read{eval{print loop (REPL) for individual functions while writing
programs.
2.1
      </p>
      <p>Examples from the REPL
{ Create an axiom
fowl.core=&gt; (ont/implies (ont/exists "r" "a") "b")</p>
      <p>SubClassOf(ObjectSomeValuesFrom(r a) b)
1 https://leiningen.org/
2 https://github.com/aaronEberhart/fOWL
3 https://clojars.org/onto.aaroneberhart/fowl
4 https://cljdoc.org/d/onto.aaroneberhart/fowl/0.0.1-SNAPSHOT/doc/readme
{ Show the documentation for a function
fowl.core=&gt; (doc ont/makeOWLFile)
------------------------ontology.core/makeOWLFile
([ontology filename &amp; fileType])</p>
      <p>Writes an owl file of the ontology with the supplied file name.</p>
      <p>Optional argument allows choice of file type. No option defaults to functional syntax.
(Currently only functional syntax defined)
{ Make an ontology with a Clojure threading expression
fowl.core=&gt; (-&gt; ont/emptyOntologyFile
(ont/setOntologyIRI "http://www.test.iri")
(ont/addAnnotations (ont/annotation "annotations" "are fun"))
(ont/addPrefixes (ont/prefix "" "http://www.test.iri/")</p>
      <p>(ont/prefix "prefix" "http://www.prefix.iri/"))
(ont/addAxioms (ont/implies "a" (ont/IRI "prefix" "b"))
(ont/implies (ont/or "d" "g") "a")
(ont/implies (ont/inverseRole "r") "s")
(ont/fact "a" "i")
(ont/fact "r" "j" "i")))
Ontology(&lt;http://www.test.iri&gt;
Annotation(:annotations "are fun")
ObjectPropertyAssertion(:r :j :i)
SubObjectPropertyOf(ObjectInverseOf(:r) :s)
SubClassOf(ObjectUnionOf(:d :g) :a)
SubClassOf(:a prefix:b)
ClassAssertion(:a :i)
)
{ Add every third axiom from a vector into a set with a tail recursive loop
fowl.core=&gt; (loop [counter 0
axiomSet #{}
axioms [(ont/implies (ont/exists "r" "a") "b")
(ont/implies (ont/or "b" "c") (ont/not (ont/or "d" "e")))
(ont/implies (ont/roleChain "r" (ont/inverseRole "s")) "t")
(ont/fact (ont/inverseRole "s") "i" "j")
(ont/fact "a" "i")
(ont/fact "d" "i" (ont/stringLiteral "l"))
(ont/implies (ont/roleChain "s" "q") "t")]]
(if (empty? axioms)
axiomSet
(recur
(inc counter)
; are there no axioms left?
; return axiom set
; else recurse with new values
; counter + 1
(if (= 0 (mod counter 3))
(conj axiomSet (first axioms))
axiomSet)
; is counter mod 3 == 0?
; add first axiom to set
; else keep current axiom set
(rest axioms))))
; remove first axiom
#{ObjectPropertyAssertion(ObjectInverseOf(s) i j)</p>
      <p>SubClassOf(ObjectSomeValuesFrom(r a) b)
SubObjectPropertyOf(ObjectPropertyChain(s q) t)}
{ Use a partial function and a list comprehension to make axioms for a class
fowl.core=&gt; (let [aImplies (partial ont/implies "a")]</p>
      <p>(for [b ["c" (ont/all "r" "d") (ont/and "e" "f" "g")]] (aImplies b)))
(SubClassOf(a c)
SubClassOf(a ObjectAllValuesFrom(r d))</p>
      <p>SubClassOf(a ObjectIntersectionOf(e f g)))
More examples are available on the project GitHub page.
3</p>
    </sec>
    <sec id="sec-2">
      <title>Evaluation</title>
      <p>As a preliminary benchmark, we choose a few operations in (f OWL) that are
commonly used and have near equivalent counterparts in the OWL API: read
an ontology, write an ontology, get the NNF of all class axioms. Table 2 shows
the average time to complete a task, and Table 3 shows the average times when
they are each scaled by the number of axioms in the ontology. As expected,
the performance of (f OWL) with respect to the OWL API closely parallels the
di erence between native Java and Clojure. Though it is usually faster when
reading les, as indicated by the scaled times, (f OWL) is slowed down while
reading large les by the need to construct many immutable objects for the
ontology, which is typical for Clojure programs. However, even a large (f OWL)
ontology can be accessed and traversed in a very e cient manner. This allows
(f OWL) to write les quickly. And it can get the NNF of all class axioms
signi cantly faster than even optimized stream functions.</p>
      <p>All testing was done on a computer running Ubuntu 20.04.1 64-bit with an
Intel Core i7-9700K CPU@3.60GHz x 8, 47.1 GiB DDR4, and a GeForce GTX
1060 6GB/PCIe/SSE2.
4</p>
      <p>Conclusion
(f OWL) provides a lightweight functional alternative for OWL ontology
development. It has numerous bene ts that will doubtless increase as development
nalizes and it matures. (f OWL) is highly practical for developers who prefer
a functional language, it supports all of OWL 2, and provides unique functional
methods for structuring and manipulating ontology data.
5</p>
    </sec>
    <sec id="sec-3">
      <title>Future Work</title>
      <p>There are two major e orts in progress to improve this project. The rst is
writing and testing new functions to allow the parsing of XML and RDF OWL
les. This capability is integrated into the current project framework but it is
incomplete and takes a fair amount of time to test and debug. Additionally,
because OWL les are frequently in XML and RDF format we have delayed
the implementation of ontology imports until after these le types can be read.
Once the imports are implemented (f OWL) should support at least as much
semantics for standard OWL ontology development as other APIs. A custom
reasoner is also in the early stages of development for (f OWL). We hope that
this will streamline reasoning over (f OWL) ontologies by running while they are
created.</p>
      <p>Acknowledgement This material is based upon work supported by the Air Force O ce
of Scienti c Research under award number FA9550-18-1-0386.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          1.
          <string-name>
            <given-names>Gene</given-names>
            <surname>Ontology</surname>
          </string-name>
          <article-title>Consortium: The Gene Ontology (GO) database and informatics resource</article-title>
          .
          <source>Nucleic Acids Research</source>
          <volume>32</volume>
          (
          <string-name>
            <surname>Database-Issue</surname>
            <given-names>)</given-names>
          </string-name>
          ,
          <volume>258</volume>
          {
          <fpage>261</fpage>
          (
          <year>2004</year>
          )
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          2.
          <string-name>
            <surname>Horridge</surname>
            ,
            <given-names>M.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Bechhofer</surname>
            ,
            <given-names>S.:</given-names>
          </string-name>
          <article-title>The OWL API: A Java API for OWL ontologies</article-title>
          .
          <source>Semantic Web</source>
          <volume>2</volume>
          (
          <issue>1</issue>
          ),
          <volume>11</volume>
          {
          <fpage>21</fpage>
          (
          <year>2011</year>
          )
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          3.
          <string-name>
            <surname>Lamy</surname>
            ,
            <given-names>J.B.</given-names>
          </string-name>
          :
          <article-title>Owlready: Ontology-oriented programming in python with automatic classi cation and high level constructs for biomedical ontologies</article-title>
          .
          <source>Arti cial intelligence in medicine 80</source>
          ,
          <volume>11</volume>
          {
          <fpage>28</fpage>
          (
          <year>2017</year>
          )
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          4.
          <string-name>
            <surname>Lord</surname>
            ,
            <given-names>P.:</given-names>
          </string-name>
          <article-title>The semantic web takes wing: Programming ontologies with tawny-owl</article-title>
          . In:
          <string-name>
            <surname>Rodriguez-Muro</surname>
            ,
            <given-names>M.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Jupp</surname>
            ,
            <given-names>S.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Srinivas</surname>
            ,
            <given-names>K</given-names>
          </string-name>
          . (eds.)
          <source>Proceedings of the 10th International Workshop on OWL: Experiences and Directions (OWLED</source>
          <year>2013</year>
          )
          <article-title>co-located with 10th Extended Semantic Web Conference (ESWC</article-title>
          <year>2013</year>
          ), Montpellier, France, May
          <volume>26</volume>
          -27,
          <year>2013</year>
          .
          <source>CEUR Workshop Proceedings</source>
          , vol.
          <volume>1080</volume>
          .
          <string-name>
            <surname>CEUR-WS.org</surname>
          </string-name>
          (
          <year>2013</year>
          ), http://ceur-ws.
          <source>org/</source>
          Vol-
          <volume>1080</volume>
          /owled2013\_16.pdf
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          5.
          <string-name>
            <surname>Parsia</surname>
            ,
            <given-names>B.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Patel-Schneider</surname>
            ,
            <given-names>P.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Motik</surname>
            ,
            <given-names>B.</given-names>
          </string-name>
          :
          <article-title>OWL 2 Web Ontology Language Structural Speci cation and Functional-Style Syntax (Second Edition)</article-title>
          .
          <source>W3C recommendation</source>
          ,
          <source>W3C (Dec</source>
          <year>2012</year>
          ), http://www.w3.org/TR/2012/REC-owl2-syntax20121211/
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>