Repository navigation
Commit 818d2c6
The reasoner benchmark measures what it says it measures (#310)
* The Java reference emits the full entailed hierarchy, not direct superclasses
JavaReasoner.java emitted getSuperClasses(cls, true) for each class, the
DIRECT superclasses only. The engine reports every superclass in
classification[].superclasses, so a comparison between the two counted every
indirect pair the engine got right as an unsound extra. Direct superclasses
also never include equivalent classes. In ORE file ore_ont_8937 the axioms
SubClassOf(owl:Thing C23) and their siblings make C23, C25 and others
equivalent to owl:Thing, so the true pair C25 -> C23 was absent from the
reference and a correct engine answer was misread as unsound.
For every named class HermiT finds satisfiable, the output now lists every
named superclass with direct=false plus every named equivalent class.
owl:Thing and owl:Nothing never appear in a pair, and unsatisfiable classes
are listed under "unsatisfiable" instead of contributing a pair to every class
in the ontology. Run on ore_ont_8937 the reference now holds 402 pairs and
includes C25 -> C23.
The output also carries told_subsumptions, the transitive closure of the
asserted named hierarchy computed by the OWL API with no reasoner:
SubClassOf between named classes, pairwise EquivalentClasses among named
members, and the tautological edge from every named class to owl:Thing. The
benchmark driver subtracts it from the reference to isolate the pairs that
need reasoning.
Times are now reported separately instead of as one figure: JVM start to
main, parse, reasoner construction (HermiT clausifies there), and
precomputeInferences alone. time_ms remains, defined as construction plus
classification, for older callers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* The regressions note no longer claims Pizza is free of nominals
regressions/README.md said the Pizza ontology contains no owl:hasValue and
classifies in about 0.04s, and used that to argue the owl-dl blowup is
specific to nominals rather than to scale. The figure came from a stripped
566-triple fixture. The reference benchmark/reference/pizza-reference.owl
carries six owl:hasValue restrictions and one owl:oneOf enumeration of five
individuals, counted as XML elements. A line count with grep reports two
oneOf, because it also matches the closing tag; the main README repeats that
miscount and is corrected in a later commit.
The note now says what the reference file does under the current development
build: over 2,332 loaded triples, reason --profile owl-dl returns
complete: false with the budget exhausted in satisfiability and abox, 143 of
144 named classes undetermined and zero inferred subsumptions. It quotes no
run time, because the phase budgets set it.
The closing paragraph on blocking had been garbled by an earlier edit that
replaced one line of a sentence with another, leaving two half sentences. It
now says what the history shows: subset blocking was the original
implementation, pairwise blocking has since landed as is_pairwise_blocked,
and the NI-rule is still outstanding.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* The Java reference reports an inconsistent ontology instead of crashing on it
HermiT throws InconsistentOntologyException from precomputeInferences when the
ontology has no model. JavaReasoner let it propagate, so the run died with a
stack trace and the benchmark could only record that HermiT failed. ORE file
ore_ont_6720 in the EL classification track is such a file: HermiT finds it
inconsistent both in its original Functional Syntax and after conversion to
RDF/XML, so this is a property of the file, not of the conversion.
The exception is now caught and the output says consistent: false with no
pairs, which lets the driver ask the question that matters on such a file:
whether the engine also noticed, or reported a consistent ontology and a
hierarchy for it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* run_ore.py scores the engine against HermiT on the ORE 2015 corpus, pair by pair
There was no driver for the ORE 2015 classification corpus. run_ore.py takes a
track (el, dl or pure_dl) and a set of files from that track's fileorder.txt,
runs both reasoners, and writes a JSON record and a markdown table to
benchmark/reasoner/results/. It uses the Python standard library only.
Both reasoners read the same bytes. The engine does not read OWL Functional
Syntax yet, so each ORE input is converted once to RDF/XML by the OWL API
(Convert.java, now tracked) and the converted file is given to both. --native
gives the original file to both instead; until the engine reads Functional
Syntax every such run fails the load gate, which is the intended outcome.
The engine runs as one `batch -` process per run, load then reason --profile
owl-dl, under a wall-clock cap the driver enforces by killing the process
group. A run reports no timing when its load line lacks triples_loaded, has it
at 0 or carries an error, when its reason line is missing or carries an error,
when the process exits non-zero, or when the cap killed it. If any one of the
--repeat runs (default 3) fails a gate, the file reports no timing at all,
because a median over the runs that happened to finish would hide the one that
did not.
The reference is HermiT's full entailed named hierarchy from JavaReasoner. The
driver also takes the told closure from the OWL API and subtracts it, so each
file reports gold, told and inferred-only counts, and recall on all pairs and
on inferred-only pairs. A file with no inferred-only pairs is flagged
told_only and kept out of the headline, because a walk of the asserted axioms
scores 100% on it. On the six smallest files of the EL track every file is
told_only, so a headline built from them would have measured nothing about
reasoning.
Wrong answers are listed, not counted away: pairs the engine claims and HermiT
does not entail, from any repeat and not only the first; classes the engine
calls unsatisfiable that HermiT finds satisfiable; and an engine that calls
consistent an ontology HermiT finds inconsistent. The table also carries the
engine's undetermined count, budget_exhausted_in, and whether its answer was
identical across repeats.
--selftest drives fake engines through the same code and asserts that each
gate fires: an empty classification, a fabricated wrong pair, a fabricated
wrong pair in the second of three runs only, a false unsatisfiability claim, a
false consistency claim, an empty load, a load error, a missing
triples_loaded, a reason error, a crash, a hang, a hang in one repeat of
three, an answer that changes between runs, and a told-only file, plus a
correct engine and a structural walk as controls. All 17 checks pass. Each
gate was also disabled in turn in a scratch copy, and every mutation made the
self-test fail except one: with the explicit load-error check removed, a
failed load is still caught, because it also has no triples_loaded.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* The Pizza benchmark gates on keys the engine emits and compares like with like
run_pizza_correctness.sh aborted every real run with "reasoned over an empty
graph" although the load line reported 2,332 triples. Its guard read
result["classes"] or result["class_count"], and the owl-dl reason result has
neither key, so the count was always zero. The guard now requires the load
line to carry triples_loaded > 0 and no error, and the reason line to carry no
error and a non-zero named_classes, a key the result has (falling back to
agents.satisfiability_agent.classes_checked).
The guard was checked in both directions. On an empty input file it stops
with "load reported triples_loaded=0" and exit 1. On an OWL Functional Syntax
file, which the engine cannot read, it stops with the engine's own load error.
That case also exposed a second fault: the engine exits 1 when a batch command
fails, and under set -e the script ended there with no message at all. It now
captures the engine's status and lets the gate say what failed. On the real
reference file the old guard, run unchanged, still rejects the run, and the
new one accepts it: 2,332 triples loaded, 144 named classes.
compare_results.py read a "subsumptions" key from the engine result. The
engine never emits one, so the engine side was always the empty set, compared
against HermiT's direct superclasses. It now reads classification plus
equivalences and scores them with the same code as run_ore.py against the full
hierarchy from JavaReasoner, reporting gold, told and inferred-only counts,
recall on each, wrong pairs, and unsatisfiable classes on both sides.
The script ran Pellet unconditionally, so with a lib/ holding no Pellet jars
it stopped at that step under set -e. Pellet now runs only when a
pellet-*.jar or openllet-*.jar is present. JavaReasoner is compiled into target/java by the script itself, and
PIZZA_OWL, LIB_DIR, JAVA and RESULTS_DIR can be overridden.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* The reasoner benchmark README documents the ORE driver and the told-closure subtraction
The README's setup section asked for OWL API 5.x and HermiT.jar from
hermit-reasoner.net. JavaReasoner.java is compiled against OWL API 4, which is
what setup_jars.sh fetches, so the instructions now name that and list the jar
set the harness was actually run with. The scripts compile the Java sources
themselves, so no Maven step is described.
A new section says what the HermiT reference is (the full entailed named
hierarchy, not direct superclasses), why the direct form misread correct
engine answers as unsound, using ore_ont_8937 as the worked case, and which
times JavaReasoner reports separately.
The Pizza section said the reference file has two owl:oneOf enumerations. It
has one, of five individuals; the two came from a line count that also
matched the closing tag. The section now describes the gate the script
applies and the like-with-like comparison, and states that run_benchmark.py
and the committed results/pizza_comparison.json predate both fixes: the
former still runs load and reason as separate processes, and the latter
reports named_classes: 1, the signature of an empty store.
The ORE section documents run_ore.py: same bytes to both reasoners, the
--native flag, the single-process engine run under a driver-enforced cap, the
gates that withhold a timing, the told-closure subtraction and why a file with
no inferred-only pairs is excluded from the headline, the per-file fields, and
the self-test. It makes no performance claim; the engine is being changed in
parallel and the driver exists to measure it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* The ORE table names unscored files for what they are
The headline listed every file outside ok and told_only under "failed a
gate". That includes ore_ont_6720, which HermiT finds inconsistent and the
engine also reports inconsistent, so nothing failed; there is just no
hierarchy to score. The line now reads "not scored" and names the three
reasons a file can land there.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>1 parent 40bb0ab commit 818d2c6
8 files changed
Lines changed: 1303 additions & 156 deletions
File tree
- benchmark/reasoner
- regressions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
| 6 | + | |
5 | 7 | | |
6 | 8 | | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
7 | 42 | | |
8 | 43 | | |
| 44 | + | |
| 45 | + | |
9 | 46 | | |
10 | | - | |
| 47 | + | |
11 | 48 | | |
12 | 49 | | |
13 | | - | |
| 50 | + | |
14 | 51 | | |
15 | 52 | | |
16 | 53 | | |
| 54 | + | |
17 | 55 | | |
18 | 56 | | |
| 57 | + | |
19 | 58 | | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
| 59 | + | |
42 | 60 | | |
43 | | - | |
| 61 | + | |
44 | 62 | | |
45 | | - | |
46 | | - | |
| 63 | + | |
47 | 64 | | |
48 | | - | |
49 | | - | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
50 | 80 | | |
| 81 | + | |
| 82 | + | |
51 | 83 | | |
52 | | - | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
53 | 95 | | |
54 | 96 | | |
55 | 97 | | |
56 | 98 | | |
| 99 | + | |
| 100 | + | |
57 | 101 | | |
58 | | - | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
59 | 108 | | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
65 | 211 | | |
66 | | - | |
| 212 | + | |
67 | 213 | | |
68 | | - | |
| 214 | + | |
| 215 | + | |
69 | 216 | | |
70 | | - | |
71 | | - | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
72 | 230 | | |
73 | | - | |
| 231 | + | |
74 | 232 | | |
75 | 233 | | |
0 commit comments