core/evals/dimensional/oracle.py
Shay 96c1d4bcee feat: dimensional-reasoning lane — 3rd diversity-panel domain
The first non-GSM8K consumer of the binding-graph interlingua's unit algebra as a
load-bearing reasoner: given two units and an operation, decide the result's
dimension. SUT = generate.binding_graph.units; gold = evals/dimensional/oracle.py,
a genuinely INDEPENDENT dimensional reasoner (own unit->base-exponent table, own
exponent arithmetic, own canonical-string renderer; shares no code with the SUT).

12 cases (area / speed / wage / mass-density / dimensionless / 2 refused) gated by
SUT == oracle == gold (wrong=0). Registered in INV-25's INDEPENDENT_GOLD_LANES,
proving the independent-gold discipline generalizes to a SECOND oracle.

This is the 3rd structurally-distinct golded domain (logic / grounding / dimensional)
— the anti-overfit >=2-domain panel is now real, and the interlingua is load-bearing
beyond GSM8K.
2026-06-04 16:38:56 -07:00

99 lines
3.9 KiB
Python

"""Independent dimensional oracle — the gold for the dimensional-reasoning lane.
This is **deliberately a second, independent decision procedure** for "what is the
dimension of ``left <op> right``?". It carries its **own** unit→base-exponent table
and its **own** exponent arithmetic and canonical-string renderer, and shares
**no code** with :mod:`generate.binding_graph.units` (the system under test). Two
independent dimensional reasoners agreeing on the same cases is real evidence the
interlingua's unit algebra is correct; a shared-code "oracle" would only prove the
algebra agrees with itself (INV-25).
Base-dimension order matches the SUT's so the rendered strings are directly
comparable (the comparison is about the *decision*, not the spelling).
"""
from __future__ import annotations
from typing import Final
# Same axis order as the SUT's BASE_DIMENSIONS so canonical strings line up.
_BASE: Final[tuple[str, ...]] = ("length", "time", "mass", "money", "count", "temperature")
# An INDEPENDENT unit→base-exponent table (hand-authored; NOT the en_units_v1 pack
# the SUT reads). Only concrete base units; composites are resolved structurally.
_UNIT_DIMS: Final[dict[str, dict[str, int]]] = {
"meter": {"length": 1}, "mile": {"length": 1}, "foot": {"length": 1},
"second": {"time": 1}, "hour": {"time": 1}, "minute": {"time": 1}, "day": {"time": 1},
"kilogram": {"mass": 1}, "pound": {"mass": 1},
"dollar": {"money": 1},
"degree": {"temperature": 1},
}
class OracleError(ValueError):
"""Unit outside the oracle's independent vocabulary — refuse, never guess."""
def _depluralize(unit: str) -> str:
"""Independent conservative plural strip (mirrors the SUT's contract, own code)."""
if unit in _UNIT_DIMS:
return unit
for cand in (
unit[:-3] + "y" if unit.endswith("ies") and len(unit) > 3 else "",
unit[:-2] if unit.endswith("es") and len(unit) > 2 else "",
unit[:-1] if unit.endswith("s") and len(unit) > 1 else "",
):
if cand and cand in _UNIT_DIMS:
return cand
return unit
def _vector(unit: str) -> tuple[int, ...]:
"""Resolve a unit id (incl. plural and ``X_per_Y`` composites) to an exponent
tuple over ``_BASE``. Raises :class:`OracleError` on anything else."""
if not isinstance(unit, str) or not unit:
raise OracleError(f"empty unit: {unit!r}")
canon = _depluralize(unit)
if canon in _UNIT_DIMS:
dims = _UNIT_DIMS[canon]
return tuple(dims.get(b, 0) for b in _BASE)
if "_per_" in unit:
num, _, denom = unit.partition("_per_")
nv = _vector(num)
dv = _vector(denom)
return tuple(a - b for a, b in zip(nv, dv))
raise OracleError(f"unknown_unit: {unit!r}")
def _render(exps: tuple[int, ...]) -> str:
"""Canonical dimension string, format-compatible with the SUT's renderer."""
nums: list[str] = []
dens: list[str] = []
for dim, e in zip(_BASE, exps):
if e > 0:
nums.append(dim if e == 1 else f"{dim}^{e}")
elif e < 0:
dens.append(dim if e == -1 else f"{dim}^{-e}")
if not nums and not dens:
return "dimensionless"
num_part = "*".join(nums) if nums else "1"
return num_part if not dens else f"{num_part}/{'*'.join(dens)}"
def dimensional_result(op: str, left: str, right: str) -> str:
"""The oracle verdict: the canonical dimension of ``left <op> right``.
``op`` is ``"product"`` or ``"quotient"``. Returns ``"refused"`` if either
unit is outside the oracle's vocabulary or ``op`` is unknown — the same
refusal posture as the SUT.
"""
try:
lv = _vector(left)
rv = _vector(right)
except OracleError:
return "refused"
if op == "product":
return _render(tuple(a + b for a, b in zip(lv, rv)))
if op == "quotient":
return _render(tuple(a - b for a, b in zip(lv, rv)))
return "refused"