Skip to content

Upgrade horned-owl 1.4 -> 3.x and drop the [patch.crates-io] fork (unblocks publishing owl-dl-cli / cargo install rustdl) #99

Description

@micheldumontier

Why this exists

crates/owl-dl-cli is publish = false and crates/rustdl ships no [[bin]], and the recorded
reason was that the Manchester-syntax reader was "not yet in upstream horned-owl". That is no
longer true and had not been true for weeks.
phillord/horned-owl#176 merged on 2026-07-11, and
io::omn ships in released horned-owl 2.0.0 (2026-07-17) and 3.0.0 (2026-08-10). The stale
claim is corrected in-tree as of e4a857d.

What actually blocks the CLI is narrower and more concrete:

  1. this workspace pins horned-owl = "1.4" and io::omn first appears in 2.0, so dropping the
    [patch.crates-io] fork is a major-version upgrade, 1.4 -> 3.x; and
  2. one item the fork carries did not go upstream.

What is present upstream vs. fork-only

Probed against docs.rs for 2.1.0 and 3.0.0:

path rustdl needs upstream 3.0.0
io::omn::reader::read present
io::omn::reader::parse_class_expression present
io::omn::AsManchester 404 - fork-only

Upstream merged the reader plus a whole-ontology io::omn::writer::write. The fork's per-item
AsManchester trait did not land, and writer::write cannot substitute: it serialises an entire
ontology, whereas explanations render one axiom at a time.

AsManchester is reached through .as_manchester_with_prefixes(&pm) at 6 call sites in 3 crates:

  • crates/owl-dl-cli/src/main.rs:1744, 1820, 1919, 1949 (justify / explain output)
  • crates/owl-dl-cli/src/report.rs:85 (HTML report)
  • crates/owl-dl-py/src/explain.rs:14 (Python explain surface)

Licence constraint: horned-owl is LGPL-3.0 and rustdl is Apache-2.0/MIT, so copying the
fork's implementation into this workspace is not clean. The options are to reimplement per-item
Manchester rendering over our own IR, or to upstream AsManchester to horned-owl.

Migration scale (measured 2026-09-03)

  • 170 files, 976 horned_owl:: references, 49 distinct paths.
  • Concentrated: the top four paths are 739 / 976 = 76% -
    ontology::set::SetOntology (222), io::ofn::reader::read (182), model::RcStr (171),
    io::ParserConfiguration (164).
  • All six core paths rustdl depends on (SetOntology, ofn::reader::read, RcStr,
    ParserConfiguration, ForIRI, Build) were probed present at 3.0.0 - so the count is
    breadth, not necessarily breakage. The real work is wherever 2.0/3.0 changed signatures or
    semantics, which has not been surveyed yet. Do that first; it sizes everything else.

Scope of work

  1. Diff upstream 1.4 -> 2.0 -> 3.0 for the 49 paths; produce a breaking-change list. Gate: do
    this before committing to the rest.
  2. Decide AsManchester: reimplement over rustdl's IR, or upstream it.
  3. Migrate, drop [patch.crates-io], drop the fork pin.
  4. Flip owl-dl-cli to publish = true and add [[bin]] to crates/rustdl so
    cargo install rustdl works.

Evidence bar

This changes the parser under every engine, so it does not ship on a green cargo test. It
needs the full treatment this repo requires of any change to conversion:

  • ./scripts/run-soundness-diff.sh - FP=0, all 11 curated closures exact.
  • A 1,920-ontology two-arm ORE sweep with --digest-strip-comments, arm order alternated (a
    fixed order buys a ~3.4% page-cache phantom), single-thread, on an idle host - reporting answer
    identity, not just wall.
  • Note the corpus is not self-validating here: a parser change can alter which axioms enter the
    KB at all. Adjudicate any DIFFER against Konclude/HermiT rather than assuming noise.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions