Skip to content

Make the disabled state of OWLAPI reasoning explicit, and stop implying it in tests #312

Description

@alexskr

The ask

BioPortal does not support reasoning. Right now the code does not say that — it ends up disabled by accident, through a predicate that can never return true, while the surrounding plumbing and the test fixtures still read as if reasoning were a supported, sometimes-on feature. Two concrete things:

  1. Make the disabled state deliberate in the code, with a comment saying BioPortal does not do reasoning, instead of relying on a contradiction that reads like a typo (and that a future "cleanup" would likely "fix" into turning the reasoner on).
  2. Stop passing reasoning: true in the tests (18 occurrences across 5 files: test/models/test_class.rb, test/models/test_skos_submission.rb, test/models/test_ontology_submission.rb, test/models/test_class_portal_lang.rb, test/util/test_ontology_csv_writer.rb). Those arguments do nothing today, but they document a behavior we don't have, and any test that came to depend on reasoner-materialized triples would be resting on a fiction.

Whether to remove the reasoning feature entirely is a separate question and explicitly out of scope here. This issue is about making the current state honest.

Current state

SubmissionProcessor#process_reasoning? uses && where every sibling predicate uses ||:

# lib/ontologies_linked_data/services/submission_process/submission_processor.rb
def process_metrics?(options)
  options.empty? || options[:run_metrics].eql?(true)
end

def process_reasoning?(options)
  options.empty? && options[:reasoning].eql?(true)   # <-- can never be true
end

The conjuncts are mutually exclusive: if options is empty then options[:reasoning] is nil, which is never .eql?(true); if options[:reasoning] is true then options is not empty. So generate_rdf always receives reasoning: false and always calls owlapi.disable_reasoner.

Note that flipping && to || would not enable reasoning — see the evidence below. It would only make the Ruby side pass -r true to a jar that discards it.

Why it produces no observable difference

lib/ontologies_linked_data/parser/owlapi.rb:16 invokes owlapi-wrapper-1.5.1.jar with -r true|false. In that jar:

  • useReasoner appears only in ParserInvocation — the private field plus its getter/setter. OntologyParser, the class that generates the RDF, never reads it. (Bytecode scan of every class under org/stanford/ncbo/owlapi/wrapper/; same in 1.5.0.)
  • No DL reasoner is bundled — no HermiT, Pellet, ELK or JFact. Only OWLAPI's own StructuralReasoner, which ships with the library.

Confirmed empirically by parsing the same file twice, forcing process_reasoning? to return true for the second run and verifying the jar received @reasoning = true:

fixture flag triples rdfs:subClassOf subClassOf owl:Thing classes
BRO_v3.2.owl (OWL) -r false 4400 505 12 487
BRO_v3.2.owl (OWL) -r true 4400 505 12 487
hp.obo (OBO) -r false — — 1 (treeView) 32
hp.obo (OBO) -r true — — 1 (treeView) 32

Identical in every counted dimension. Both fixtures are plain taxonomies with little to infer, so the table alone would be weak evidence — but the bytecode scan is not content-dependent: the flag is never consulted, whatever the input.

How it got here

2013 — a real reasoner, briefly. 6d6a3aa2 (2013-08-27) "owlapi wrapper with hermit reasoner" bundles HermiT, growing the jar from 2.4 MB to 5.7 MB, off the reasoner_roots branch. 42052023 / 18e8c972 / 17a2238e (2013-08-30) add the opt-out plumbing that still exists today: @reasoning = true default, disable_reasoner, and the reasoning: kwarg through generate_rdf.

2013 — downgraded within 11 days. 42050ab9 (2013-09-07) "NCBO-171 owlapi wrapper with structural reasoning" swaps the jar again, replacing HermiT with OWLAPI's StructuralReasoner — which is what is still bundled today and is not a DL reasoner. fab2d024 (2013-09-30) "change in children stats due to structural reasoning" adjusts for the fallout.

2014 — walked back further. 50b6e900 (2014-04-16) "NCBO-712 Remove reasoning when flagging obsolete classes".

At some point after that the wrapper stopped consulting the flag at all, leaving the Ruby plumbing vestigial. (For the record: I looked for the reasoning work in ncbo/4store and upstream 4store/4store and found no reasoning-named branches in either; the adjacent artifacts from that period are goo-level sub-property reasoning and query-time inferencing, e.g. 4d075af3 2013-01-29 "Enable inferencing in Class queries to retrieve standard slots".)

2024 — the && is written, in AgroPortal. Commit 91d5642f (2024-04-20, syphax-bouazzouni), "add the global submission process that call the sub-steps", in agroportal/ontologies_linked_data#132 "Feature: isolate ontology submission process steps" — the refactor that replaced get_options with per-option predicates. The get_options block it deleted had the opt-out shape from 2013:

-            if !process_rdf || options[:reasoning] == false
-              reasoning = false
-              reasoning = true

So the refactor inverted a default-on into an always-off, for AgroPortal as well. Released in their 2.6.0 (2bc3c98c, PR #135, 2024-05-22). Nothing is filed about reasoning in their tracker, consistent with the flag already being inert by then.

2026 — integrated here. 836b2dce (2026-01-16, mdorf, "incremental integration commit") brought the refactor into ncbo, ~21 months later; reached master via 4d031beb (2026-07-31).

Divergence worth knowing about: ontoportal/ontologies_linked_data never took this refactor. It still has the original get_options with the default-on resolution. So the && exists only in agroportal and ncbo, and the two lineages currently disagree about whether reasoning is on by default.

Suggested shape of the change

  • process_reasoning? returns false outright, with a comment stating BioPortal does not support reasoning and that the wrapper ignores -r regardless.
  • Drop reasoning: true from the test fixtures; leave the parse behavior as-is (it already is what the tests get).
  • Leave disable_reasoner, @reasoning, the -r flag and the reasoning: kwarg in place for now — removing them is the separate question.

Location

  • lib/ontologies_linked_data/services/submission_process/submission_processor.rb — process_reasoning?
  • lib/ontologies_linked_data/services/submission_process/operations/submission_rdf_generator.rb — owlapi.disable_reasoner unless reasoning
  • lib/ontologies_linked_data/parser/owlapi.rb — @reasoning default, disable_reasoner, -r flag
  • test/models/test_class.rb, test/models/test_skos_submission.rb, test/models/test_ontology_submission.rb, test/models/test_class_portal_lang.rb, test/util/test_ontology_csv_writer.rb — reasoning: true arguments

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