conceptual-taxonomy
Find class abstractions — rdfs:subClassOf hierarchies — in a conceptual schema, whatever
kind of database it came from.
pip install conceptual-taxonomy
from conceptual_taxonomy import discover_abstractions
result = discover_abstractions(bundle) # a {conceptualSchema, physicalMapping} bundle
result.abstract_classes # proposed classes, with evidence
result.subclass_edges # proposed subClassOf edges
merged = result.merge_into(bundle) # additive; never rewrites what is already there
Pure function. No database access, no connectors, no credentials, no I/O. Same input, same output, every time.
The problem it solves
A database stores Account → {Checking, Savings, Mortgage, Insurance} in any of several ways:
one table with a type column; a parent table plus subtype tables joined on a shared key; four
independent tables with the common columns copied into each; and the ArangoDB equivalents of
all three. Same concepts, completely different physical shapes.
All of them must produce the same conceptual answer. That is the whole requirement, and it is what the fixture set tests: one bank-account taxonomy in eight encodings, one expected result.
Designed as a companion to
arango-schema-analyzer and
relational-schema-analyzer, which
already emit the same {conceptualSchema, physicalMapping, metadata} bundle shape. Neither
discovers abstractions today, and the logic is identical for both — so it lives here rather
than being written twice.
Why one implementation and not two
An abstraction must separate properties present on every subclass from those present on only some:
top.shared_properties # [{"name": "balance", ...}] → SUM(balance) across all accounts is sound
top.partial_properties # [{"name": "monthlyPayment", "presentOn": ["MortgageAccount"],
# "coverage": 0.25}] → SUM(monthlyPayment) reads 1 of 4 subclasses
Aggregating over the second kind silently under-reports, with no error. Two implementations would drift on that boundary, and the drift shows up as one of them answering confidently and wrong. That is a correctness argument for sharing, not a tidiness one.
How it finds them
Four mechanisms; the first three are deterministic and need no LLM.
| Mechanism | Finds | |
|---|---|---|
| 4.1 | Discriminator values | one container + a type column |
| 4.2 | Formal concept analysis | sibling tables with a shared property core and no parent |
| 4.3 | Shared-key subsumption | a child keyed on its parent's key, and the ER specialization pattern |
| 4.4 | Naming hook (optional LLM) | a domain name where morphology gives none |
Concept analysis yields a genuine lattice, so multi-level taxonomies come out multi-level:
Account → FinancialAccount → Checking alongside Account → InsuranceAccount.
Mechanism 4.4 may only rename or subdivide what the deterministic mechanisms produced — it can never introduce a class none of them proposed.
Output is proposals, not facts
Every class and edge carries mechanism, confidence, and evidence, and merge_into is
additive and reversible. Consumers are expected to arbitrate: schema-derived taxonomy will
compete with taxonomy extracted from documents and from cross-ontology alignment, and
resolving those conflicts — cycle detection, disjointness checking, human curation — belongs
downstream, not here.
Correspondingly, this library does no consistency checking of its own.
Disjointness and completeness, measured rather than assumed
Where the caller supplies key-overlap counts, the ER specialization constraints are derived:
disjoint when no parent key appears in two subtypes, complete when every parent key appears
in one. Unmeasured yields None — never False. Absence of evidence is not evidence of
absence, and blanket disjointness assertions are how schema-to-OWL pipelines produce
unsatisfiable ontologies.
Not in scope
- Database access — input is a bundle, output is a bundle fragment
- Foreign-key inference — paradigm-specific; lives in the two analyzers
- Query generation — consumers compile abstractions into AQL / SQL / SPARQL themselves
Documentation
docs/SPEC.md— the contract, mechanism by mechanismfixtures/README.md— the worked example, and the bugs it caughtdocs/CROSS-REPO-PLAN.md— how this fits the surrounding work
Known limits
- A class needs at least 3 shared properties (
min_abstraction_intent). Four entities sharing only{id, balance}will not produce a parent — the evidence is too thin to separate a real abstraction from "these happen to be tables." - Synthesized intermediate classes cannot be named deterministically. When every subtype
ends in
Account, morphology yieldsAccountfor the middle layer too, so it gets the placeholderAccountByRoutingNumber. Structure is right; supply anamer(mechanism 4.4) to getFinancialAccount. - A schema with no contrast entities is judged with lower confidence. If every entity
belongs to the taxonomy, no property can be told apart from audit boilerplate by frequency,
so the shared set is reported as-is and
evidence.lowContrastis set.
Status
Pre-1.0 and moving. The API is one function and will change as real analyzers feed it —
pin a version. See CHANGELOG.md.
License
Apache-2.0, matching the surrounding Arango ecosystem libraries.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file conceptual_taxonomy-0.1.1.tar.gz.
File metadata
- Download URL: conceptual_taxonomy-0.1.1.tar.gz
- Upload date:
- Size: 25.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98b7444eab0844c3b87ea9103c4bc86ad8ba664d803974ad1f041896abee592a
|
|
| MD5 |
65ccd65f27b69485af612d90ac9c4230
|
|
| BLAKE2b-256 |
9e9fe9699fb7c0231ec2427b9fc7bcd5d1b8aacb07696f413989c21d45e5f00c
|
File details
Details for the file conceptual_taxonomy-0.1.1-py3-none-any.whl.
File metadata
- Download URL: conceptual_taxonomy-0.1.1-py3-none-any.whl
- Upload date:
- Size: 22.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0a2dde9442478ae7bebc930db595ce0aaf1dc16030968abb76080883230e0dd
|
|
| MD5 |
3db153757abe16762c2d7b5cf0266f05
|
|
| BLAKE2b-256 |
21ef44fd26c431431a3467b9806ddac489fdca1a181912ac4ba9ec0186f3bc32
|