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:
- 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).
- 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
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:
reasoning: truein 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||:The conjuncts are mutually exclusive: if
optionsis empty thenoptions[:reasoning]isnil, which is never.eql?(true); ifoptions[:reasoning]istruethenoptionsis not empty. Sogenerate_rdfalways receivesreasoning: falseand always callsowlapi.disable_reasoner.Note that flipping
&&to||would not enable reasoning — see the evidence below. It would only make the Ruby side pass-r trueto a jar that discards it.Why it produces no observable difference
lib/ontologies_linked_data/parser/owlapi.rb:16invokesowlapi-wrapper-1.5.1.jarwith-r true|false. In that jar:useReasonerappears only inParserInvocation— the private field plus its getter/setter.OntologyParser, the class that generates the RDF, never reads it. (Bytecode scan of every class underorg/stanford/ncbo/owlapi/wrapper/; same in 1.5.0.)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:rdfs:subClassOfsubClassOf owl:ThingBRO_v3.2.owl(OWL)-r falseBRO_v3.2.owl(OWL)-r truehp.obo(OBO)-r falsetreeView)hp.obo(OBO)-r truetreeView)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 thereasoner_rootsbranch.42052023/18e8c972/17a2238e(2013-08-30) add the opt-out plumbing that still exists today:@reasoning = truedefault,disable_reasoner, and thereasoning:kwarg throughgenerate_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'sStructuralReasoner— 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/4storeand upstream4store/4storeand 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.4d075af32013-01-29 "Enable inferencing in Class queries to retrieve standard slots".)2024 — the
&&is written, in AgroPortal. Commit91d5642f(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 replacedget_optionswith per-option predicates. Theget_optionsblock it deleted had the opt-out shape from 2013: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 intoncbo, ~21 months later; reachedmastervia4d031beb(2026-07-31).Divergence worth knowing about:
ontoportal/ontologies_linked_datanever took this refactor. It still has the originalget_optionswith the default-on resolution. So the&&exists only inagroportalandncbo, and the two lineages currently disagree about whether reasoning is on by default.Suggested shape of the change
process_reasoning?returnsfalseoutright, with a comment stating BioPortal does not support reasoning and that the wrapper ignores-rregardless.reasoning: truefrom the test fixtures; leave the parse behavior as-is (it already is what the tests get).disable_reasoner,@reasoning, the-rflag and thereasoning: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 reasoninglib/ontologies_linked_data/parser/owlapi.rb—@reasoningdefault,disable_reasoner,-rflagtest/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: truearguments