Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PyLogMap

A Python reimplementation of LogMap — the logic-based ontology matching and alignment-repair system — with a CPython C extension for its performance-critical kernels.

PyLogMap takes two OWL ontologies and produces a set of mappings (an alignment) between their entities, then repairs that alignment so the merged result stays logically coherent. It reproduces LogMap's behavior (verified against the original Java on the OAEI Conference and Anatomy tracks) and adds extensions for multilingual matching, external-oracle (e.g. LLM) mapping decisions, and mediated matching through any bridge ontologies.

Install

python -m pip install pylogmap

Requires Python ≥ 3.10. A C compiler is optional — without one, PyLogMap uses pure-Python kernels (slower, identical results). Optional backends ship as separate extras (see Extensions):

python -m pip install 'pylogmap[multilingual]'   # offline label translation
python -m pip install 'pylogmap[bioportal]'      # BioPortal mediating-ontology source
python -m pip install 'pylogmap[llm]'            # LogMapLLM oracle plugin
python -m pip install 'pylogmap[rag]'            # LLM oracle + semantic RAG encoders
python -m pip install 'pylogmap[plugins]'        # all optional plugins

From a checkout, use python -m pip install -e '.[dev]' (see Verification).

Quick start

Match two ontologies and write the alignment to a directory:

pylogmap match onto1.owl onto2.owl -o out/

out/ now contains the alignment in three formats plus diagnostics and a manifest (see Output files). The same thing from Python:

import pylogmap

result = pylogmap.match("onto1.owl", "onto2.owl", output_dir="out")
index = result.index

for m in result.mappings.active():
    print(index.iri_for_id(m.src), m.direction.name, index.iri_for_id(m.tgt),
          round(m.confidence, 3))

print("unsatisfiable classes after repair:", result.manifest["unsatisfiable_classes"])

Without output_dir the result stays in memory; write it later with from pylogmap.io import write_jsonl then write_jsonl(result.mappings, "alignment.jsonl", result.index).

Recipes

Full matching + repair (the default)

pylogmap match a.owl b.owl -o out/ runs the faithful LogMap pipeline: it alternates matching and logical repair per layer (layered mode). This is what you want in most cases.

Fast, repair-free matching (the "LogMap Lite" equivalent)

The old LogMap Lite was a stripped-down matcher with no logical repair. In PyLogMap that is simply repair turned off — you keep the better lexical matching and just skip the Dowling–Gallier passes:

pylogmap match a.owl b.owl -o out/ --config lite.toml
# lite.toml
clean_dg = false          # no logical repair (Lite behaviour)
property_matching = false # classes only, like Lite
instance_matching = false

Or in Python: pylogmap.match("a.owl", "b.owl", PyLogMapConfig(clean_dg=False)).

Matching through bridge ontologies (the "LogMapBio" equivalent)

The old LogMap Bio improved biomedical matching by routing through mediating ontologies downloaded from BioPortal. PyLogMap generalizes this to any set of mediating ontologies you provide — no account needed:

pylogmap match a.owl b.owl -o out/ --mediate reference1.owl reference2.owl mediators/

It matches a→each mediator and each mediator→b, composes the mappings that agree through a shared bridge concept, keeps the well-voted ones, and repairs the union. For the original BioPortal-backed behavior:

export PYLOGMAP_BIOPORTAL_API_KEY=...            # needs pip install 'pylogmap[bioportal]'
pylogmap match a.owl b.owl -o out/ --mediate-bioportal --max-mediators 10

See mediation.md.

Repair an alignment you already have

Give PyLogMap two ontologies and an existing alignment (OAEI RDF, TSV, or JSONL); it removes/weakens the mappings that make the integration incoherent — the standalone repair facility, equivalent to Java LogMap's LogMap2_RepairFacility:

pylogmap repair a.owl b.owl alignment.rdf -o out/
result = pylogmap.repair_alignment("a.owl", "b.owl", "alignment.rdf", output_dir="out")
print("removed:", len(result.report.removed), "weakened:", len(result.report.weakened))

Reuse an index across runs

Building the joint index dominates runtime on large ontologies. Build it once, match many times:

pylogmap index a.owl b.owl -o pair.plmx
pylogmap match pair.plmx -o out/
pylogmap repair pair.plmx alignment.rdf -o out/

Cross-lingual matching

Translate labels into a pivot language (offline OPUS-MT models by default) so differently-languaged ontologies match:

pylogmap fetch-translation-models de en          # once, needs pip install 'pylogmap[multilingual]'
pylogmap match german.owl english.owl -o out/ --multilingual

See multilingual.md.

Oracle decisions (the "LogMapLLM" workflow)

Let an oracle answer the mappings LogMap is uncertain about. PyLogMap exports the uncertain candidates with their surrounding context (labels, synonyms, hierarchy, siblings, attributes); the oracle judges them; PyLogMap re-runs with the answers. The harness works with any external annotator via files:

pylogmap match a.owl b.owl -o out/ --emit-questions   # writes out/questions.jsonl
# ... annotate questions.jsonl with your tool → answers.csv (uri1,uri2,true|false) ...
pylogmap match a.owl b.owl -o out/ --oracle answers.csv

LogMapLLM built in: the LogMapLLM oracle ships as an optional plugin (pip install 'pylogmap[llm]') that answers the questions with any OpenAI-compatible endpoint (OpenRouter, vLLM, SGLang), with optional RAG few-shot retrieval:

export PYLOGMAP_LLM_API_KEY=...                       # e.g. an OpenRouter key
pylogmap match a.owl b.owl -o out/ --oracle llm       # in-process
pylogmap ask-llm out/questions.jsonl -o answers.jsonl # or offline, file-to-file
pylogmap build-rag-corpus a.owl b.owl train.rdf -o corpus.jsonl

The applied decisions are logged to out/oracle_decisions.jsonl for reproducible replay, and answers are compatible with the Java LogMapLLM format. See oracle-llm.md (harness) and llm-oracle.md (plugin).

Configuration

Every threshold and toggle lives in the frozen PyLogMapConfig dataclass, with the same defaults as Java LogMap (good_isub_anchors = 0.98, good_confidence = 0.50, confidence weights 0.5/0.0/0.3/0.2, …). Pass a TOML file or build the dataclass:

pylogmap match a.owl b.owl -o out/ --config pylogmap.toml --mode sequential
from pylogmap.config import PyLogMapConfig
cfg = PyLogMapConfig(mode="sequential", use_stemming=True, instance_matching=False)
result = pylogmap.match("a.owl", "b.owl", cfg)

Common knobs: mode (layered default, or sequential = match everything then repair once), clean_dg (logical repair on/off), property_matching / instance_matching, use_stemming, output_equivalences_only. Extension settings are nested tables ([tool.pylogmap.oracle], [tool.pylogmap.mediation], …). The full field table, each default cross-referenced to the Java line it preserves, is in pipeline-io.md §5; extension config is in plugins.md §5.

Output files

Each match/repair output directory contains:

File Contents
alignment.rdf The alignment in OAEI RDF format (interoperable with other matchers)
alignment.tsv The alignment as tab-separated src tgt relation confidence kind
alignment.jsonl Lossless native format (all fields, re-readable by PyLogMap)
discarded.tsv, hard-discarded.tsv Mappings dropped by matching heuristics
conflictive.tsv, weakened.tsv Mappings removed or narrowed by logical repair
manifest.json Config, kernel backend, per-stage timings and counts, final coherence check
questions.jsonl (--emit-questions only) self-contained uncertain mapping contexts
oracle_decisions.jsonl (external-oracle runs only) replayable verdict log

--mode, output_equivalences_only, and the output_*_mappings flags control what is written.

Architecture

PyLogMap is organized around LogMap's three component types, made explicit and decoupled:

  • Indexing turns two OWL ontologies into one joint, integer-indexed structure: lexical inverted files, an interval-labelled class hierarchy for fast subsumption/disjointness queries, and a propositional Horn encoding of the told axioms.
  • Matching reads that index and produces scored candidate mappings (exact anchors → stemming/weak candidates → ambiguity decisions → properties → instances).
  • Repair removes or weakens the mappings that make the merged theory incoherent (Dowling–Gallier Horn-SAT diagnosis).

Matching and repair never import each other — they communicate only through the shared data contracts, an architecture enforced in CI by import-linter. A pipeline orchestrator runs them interleaved per layer (layered, faithful to Java LogMap) or strictly sequentially (sequential). The hot kernels (ISUB string similarity, postings intersection, interval-labelling build/query, disjointness queries, Horn-SAT propagation) are C, each with a bit-identical pure-Python fallback selected automatically. Optional plugins attach through injected protocols without the core depending on them.

Package Role Spec
pylogmap.contracts Mapping/MappingSet, the joint OntologyIndex + query API, extension protocols, .plmx serialization contracts.md, plugins.md §4
pylogmap._kernels Backend dispatcher, pure-Python kernels, optional C extension kernels.md
pylogmap.lexical Tokenization, Paice stemming, normalizers, UMLS tables indexing.md §2–3
pylogmap.indexing OWL ingestion (py-horned-owl), joint index, interval labelling, overlapping/modules indexing.md
pylogmap.matching Anchors, candidates, confidence, ambiguity, property/instance stages matching.md
pylogmap.repair Horn encoding, Dowling–Gallier diagnosis, repair plans, standalone facility repair.md
pylogmap.io OAEI RDF, TSV, native JSONL; run outputs; P/R evaluation pipeline-io.md §4
pylogmap.pipeline Layered/sequential orchestration, oracle harness, mediation engine, match()/repair_alignment() pipeline-io.md §1–3
pylogmap.plugins Optional translation backends + BioPortal mediator source plugins.md

The design handout starts at specs/SPEC.md (architecture, import rules, what was ported vs dropped from the Java tree). Implementation is tracked as work packages under specs/workpackages/.

The original Java implementation is vendored untouched in logmap-matcher/ and used as the behavioral reference and parity oracle.

Verification

From a checkout:

python -m pip install -e '.[dev]'
pytest -m 'not parity and not nightly and not external'       # unit + property tests
PYLOGMAP_PURE_PYTHON=1 pytest -m 'not parity and not nightly and not external'
ruff check src tests benchmarks && mypy && lint-imports        # static gates

The parity suite compares PyLogMap against the bundled Java reference on the OAEI Conference track (21 committed oracle bundles under tests/data/oracle/):

python tests/data/fetch_datasets.py conference
(cd logmap-matcher && mvn package -DskipTests)
pytest -m parity tests/parity/test_index_counts.py tests/parity/test_conference.py
pytest -m parity tests/parity/test_repair_facility.py

Anatomy data and its oracle are local/nightly; commands are in specs/verification.md. Live-backend plugin tests are marked -m external and run only when the relevant credentials are present.

Parity status

Gate Result
P1–P3 Conference (21 ontology pairs) Pass: 21/21 with C and forced-Python kernels
P4 standalone repair Pass with both kernel backends
P5 OAEI RDF interoperability Pass in both directions on all 21 pairs
P6 Anatomy Pass: anchors within 1.57%; Jaccard 0.9852; F-score delta 0.00124; zero final D&G conflicts

On the Anatomy pair, layered mode with C kernels takes 10.29 s and 270 MB peak RSS, versus 11.09 s for Java on the same machine; the pure-Python kernels take 112.34 s and produce the same alignment. Full numbers in benchmarks/BASELINE.md.

Contributors & references

Contributors: Pedro Giesteira Cotovio, Jon Dilworth, Ernesto Jiménez-Ruiz.

PyLogMap reimplements the algorithms of LogMap, created by Ernesto Jiménez-Ruiz and Bernardo Cuenca Grau at the University of Oxford and continued at City St George's, University of London. Citation metadata for this repository is in CITATION.cff. If you use PyLogMap in academic work, please cite the original LogMap papers:

  • Ernesto Jiménez-Ruiz, Bernardo Cuenca Grau. LogMap: Logic-based and Scalable Ontology Matching. In: The Semantic Web – ISWC 2011. LNCS 7031, pp. 273–288. Springer, 2011. doi:10.1007/978-3-642-25073-6_18 (PDF)

  • Ernesto Jiménez-Ruiz, Bernardo Cuenca Grau, Yujiao Zhou, Ian Horrocks. Large-scale Interactive Ontology Matching: Algorithms and Implementation. In: ECAI 2012. Frontiers in AI and Applications, vol. 242, pp. 444–449. IOS Press, 2012. doi:10.3233/978-1-61499-098-7-444 (PDF)

  • Sviatoslav Lushnei, Dmytro Shumskyi, Severyn Shykula, Ernesto Jiménez-Ruiz, Artur d’Avila Garcez. Large Language Models as Oracles for Ontology Alignment. In: Proceedings of the 19th Conference of the European Chapter of the Association for Computational Linguistics (Volume 1: Long Papers), pp. 2435–2449. Association for Computational Linguistics, 2026. doi:10.18653/v1/2026.eacl-long.110 (PDF)

The LLM harness follows the LogMapLLM line of work; the mediation and repair components draw on the LogMapBio and conservativity-repair literature listed in the original repository's README.

License

Apache-2.0. See LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages