Hermes provides optional OWL reasoning for post-coordinated expressions using the OWL API and the ELK reasoner.
OWL reasoning provides:
OWL reasoning is opt-in. The OWL libraries are not included in the release jar or Homebrew install — they add ~30MB and most users don't need them.
| Install method | OWL support |
|---|---|
Homebrew (hermes) | No |
Release jar (hermes.jar) | No |
From source with :owl alias | Yes |
Without OWL, hermes still provides structural subsumption and expression validation — which handles the majority of use cases.
OWL axiom reference set files must be imported. Use the --owl flag during
import:
clj -M:run:owl --db snomed.db import ~/Downloads/snomed-2024/ --owl
clj -M:run:owl --db snomed.db index compact
Or with automated download:
clj -M:run:owl --progress --db snomed.db \
install --dist uk.nhs/sct-clinical --api-key trud-api-key.txt --cache-dir /tmp/trud --owl \
index compact
# HTTP server
clj -M:run:owl --db snomed.db --owl serve
# MCP server
clj -M:run:owl --db snomed.db --owl mcp
The reasoner initialises at startup. Check its status:
curl -s 'http://localhost:8080/v1/snomed/status' | jq .reasoningStatus
# => "active", "inactive", or "unavailable"
curl -s 'http://localhost:8080/v1/snomed/classify?expression=73211009:363698007=84301002' | jq .
Returns:
equivalent-concepts — pre-coordinated concepts equivalent to the expressiondirect-super-concepts — immediate supertypesproximal-primitive-supertypes — nearest primitive ancestorscurl -s 'http://localhost:8080/v1/snomed/necessary-normal-form?expression=73211009:363698007=84301002' | jq .
The NNF uses proximal primitive supertypes as focus concepts with all necessary relationships — a canonical form useful for comparison and storage.
curl -s 'http://localhost:8080/v1/snomed/subsumes?a=73211009&b=73211009:363698007=84301002&mode=owl' | jq .
The mode=owl parameter uses the ELK reasoner instead of structural comparison.
| Structural (default) | OWL | |
|---|---|---|
| Available in | All installs | Source with :owl alias only |
| Handles GCI axioms | No | Yes |
| Handles role composition | No | Yes |
| Speed | Microseconds | Milliseconds |
| Sufficient for most use cases | Yes | — |
Structural subsumption normalises both expressions and compares them structurally. This works correctly for the vast majority of cases. OWL reasoning is needed only when GCI axioms or advanced DL features affect the subsumption relationship.
Add the OWL dependencies to your project:
;; deps.edn
net.sourceforge.owlapi/owlapi-apibinding {:mvn/version "5.5.1"
:exclusions [net.sourceforge.owlapi/owlapi-rio
net.sourceforge.owlapi/owlapi-oboformat
net.sourceforge.owlapi/owlapi-tools]}
io.github.liveontologies/elk-owlapi {:mvn/version "0.6.0"}
Then:
(require '[com.eldrix.hermes.core :as hermes])
(def svc (hermes/open "snomed.db"))
(hermes/activate-reasoner svc)
(hermes/reasoning-status svc) ;; => :active
;; Classify
(hermes/classify-expression svc "73211009:363698007=84301002")
;; OWL subsumption
(hermes/subsumes svc "73211009" "73211009:363698007=84301002" :mode :owl)
;; Necessary Normal Form
(hermes/necessary-normal-form svc "73211009:363698007=84301002")
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |