Quickstart
This walkthrough runs the core Ontopoiesis workflow against bundled sample ontologies. It teaches one idea: build a projection once, then reuse that graph across every developer task — query, lint, diff, impact — without re-parsing the source ontology.
Prerequisites¶
This quickstart assumes you are running from the repository root with the development environment already set up. If you have not done that yet, start with the installation guide.
You need:
- Python 3.11 or later and
uv - the Python workspace dependencies installed
From a fresh checkout:
1. Build A Projection¶
Start with the bundled family ontology:
On the current sample this produces a small graph projection with 47 nodes and
63 edges. That .lbug file is the artifact every later step reuses — querying,
linting, tests, diffing, and impact analysis all read it directly, so no
subsequent command re-parses the OWL document.
2. Interrogate The Graph With Cypher¶
Start by asking what kinds of OWL constructs are present:
uv run ontopoiesis query /tmp/family.lbug -q "MATCH (n:N) RETURN DISTINCT n.kind AS kind ORDER BY kind"
On the bundled sample, you should see kinds such as:
ClassEquivalentClassesNegativeObjectPropertyAssertionObjectSomeValuesFromSubClassOf
Then ask a more structural question:
uv run ontopoiesis query /tmp/family.lbug -q "
MATCH (ax:N {kind: 'EquivalentClasses'})
-[:E {role: 'operand'}]->(cls:N {kind: 'Class'}),
(ax)-[:E {role: 'operand'}]->(restriction:N {kind: 'ObjectSomeValuesFrom'})
-[:E {role: 'property'}]->(:N {iri: 'http://example.org/hasChild'})
RETURN cls.iri AS class
ORDER BY class"
On the sample ontology, this returns http://example.org/Parent.
That is the core Ontopoiesis move: build the projection once, then interrogate it repeatedly without re-parsing the source OWL document.
3. Run The Built-In Lint Baseline¶
Use the same projection as input to the bundled structural lint rules:
On the current bundled sample, the baseline passes cleanly:
No lint violations found.
╭─ Lint Complete ─╮
│ rules 20 │
│ failures 0 │
│ warnings 0 │
╰─────────────────╯
Lint rules are Cypher checks over the same graph you queried in step 2 — the projection doubles as a quality-control surface. Teams keep the default baseline conservative, then extend it with project-specific checks.
4. Compare Ontology Versions Semantically¶
Now build two small pizza ontology versions:
uv run ontopoiesis build docs/ontopoiesis/pizza.owlxml -o /tmp/pizza_v1.lbug
uv run ontopoiesis build docs/ontopoiesis/pizza_v2.owlxml -o /tmp/pizza_v2.lbug
Then diff the two projections:
The bundled pizza_v2.owlxml adds a new class, SicilianPizza, plus the related
declaration and subclass axiom. The diff reports semantic additions — not source-file
formatting differences:
status kind iri count fingerprint ontology_iri
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
added Declaration https://exam… 1 5ca795dc1e95 https://examp…
added SubClassOf https://exam… 1 1a64b124791c https://examp…
The two rows are the Declaration of the new SicilianPizza class (the added class
entity is represented by its declaration axiom) and the new SubClassOf axiom that
places it under Pizza. The diff fingerprints constructs structurally, so unchanged
axioms and the ontology wrapper produce no rows — only genuine additions and removals
appear. If the diff output is empty, the two projections were built from the same source
file.
5. Trace Impact¶
Use impact analysis against the family projection:
On this tiny sample, the upstream result walks from the constructs that reference
hasChild back to the Ontology root:
uid kind depth iri
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
n23 Declaration 1 None
n40 ObjectSomeValuesFrom 1 None
n39 EquivalentClasses 2 None
n0 Ontology 2 None
That confirms that hasChild appears in ontology content through semantic references,
not ad hoc text search: besides its own Declaration, it is used in the
ObjectSomeValuesFrom restriction that defines Parent (Parent ≡ ∃ hasChild.Person),
which the EquivalentClasses axiom and the Ontology root reach in turn. An entity used
only in its own Declaration would appear at depth 1 alone. (uid values are assigned in
document order and are not stable across rebuilds.)
On larger ontologies, this same command becomes much more informative, because it helps answer “what statements mention this entity?”
Where To Go Next¶
Once you have a projection, the workflow can branch in several directions:
- keep exploring with
ontopoiesis query - add project-specific structural checks with
ontopoiesis test - use the bundled baseline and optional rule groups with
ontopoiesis lint - compare graph versions with
ontopoiesis diff - trace references with
ontopoiesis impact - serialize back to an OWL document with
ontopoiesis export
What matters is not the sequence. What matters is that one graph-native artifact — the projection — supports all of them.
Troubleshooting¶
Step 2 returns empty results or unexpected kinds. The projection may have been built
from a different file. Confirm the build command used docs/ontopoiesis/family.owlxml as the
source. To verify the projection directly, run:
uv run ontopoiesis query /tmp/family.lbug -q "MATCH (n:N) RETURN DISTINCT n.kind AS kind ORDER BY kind"
The output should match the kinds listed in step 2.
Step 3 fails instead of passing. The projection was not built cleanly. Rebuild it
from scratch: ontopoiesis build docs/ontopoiesis/family.owlxml -o /tmp/family.lbug and re-run
ontopoiesis lint /tmp/family.lbug.
Step 4 shows no rows. This is expected when the two projections are semantically identical. If you are expecting substantive differences, confirm the two source files differ: