solve_combined_rate(CombinedRateProblem) -> int | Refusal over effective_rate = rate_a +/- rate_b. effective_rate query returns the net (even <=0); quantity/time queries need a positive net rate (non_positive_net_rate) and exact division (non_integer_solution). Pure integer arithmetic, no float/Fraction (CMB v1 crosses no units). Off-serving. Graded by a new run_solver lane in evals/combined_rate_oracle against the committed gold. Adversarial 5-lens(+adjudicator) verification returned fix_first; both real hazards fixed: - wrong=0 breach: negative known-slot inputs (time<0/quantity<0) bypassed the eff<=0 guard and produced negative answers. FIXED UPSTREAM in model.py __post_init__ — rate_a/rate_b and the known time/quantity are now positive ints, so the illegal state is unrepresentable and the solver can never receive a negative-yielding path. Added model + gold (cmb-07d eff<0/time) + lane coverage. - doc overclaim: the solver lane does NOT grade 'two independent paths' (both solver and the oracle's _canonical_outcome delegate to model.effective_rate). Corrected both docstrings to name the true anchor (committed gold + inline-computed literal tests) and added a difference-mode inline-computed test. R3-vac came back SOLID (separate PR). gold 18/18 (6/5/7); solver lane 6/0 + 5/0; 36 CMB tests; router-hygiene + serving unchanged.
54 lines
2.7 KiB
Python
54 lines
2.7 KiB
Python
"""Exact integer combined-rate solver (CMB-b).
|
||
|
||
Solves the queried slot of a :class:`CombinedRateProblem` over the **effective rate** —
|
||
|
||
```text
|
||
effective_rate = rate_a + rate_b (combine_mode == "sum")
|
||
effective_rate = rate_a - rate_b (combine_mode == "difference")
|
||
query effective_rate: return effective_rate (well-defined even if <= 0)
|
||
query quantity: effective_rate × time (exact int)
|
||
query time: quantity ÷ effective_rate (exact int or REFUSE)
|
||
```
|
||
|
||
Two refusals, the closed CMB solver taxonomy:
|
||
|
||
- ``non_positive_net_rate`` — a ``quantity`` or ``time`` query whose net rate is ``<= 0`` cannot
|
||
accumulate or finish (and guards the ``eff == 0`` time query from dividing by zero). The
|
||
``effective_rate`` query is exempt: the net rate is a well-defined answer even when ``<= 0``.
|
||
- ``non_integer_solution`` — a ``time`` query that does not divide exactly; never rounds.
|
||
|
||
Pure integer arithmetic — **no float, no Fraction** (CMB v1 crosses no units, so no rational
|
||
conversion is needed; the reader will refuse cross-unit problems, CMB-c). Off-serving (imports no
|
||
``generate.derivation`` / ``core.reliability_gate``); deterministic. This is the runtime solver; the
|
||
oracle's ``_canonical_outcome`` is a separate gold-coherence path. Note both this solver and
|
||
``_canonical_outcome`` delegate the net-rate arithmetic to ``model.effective_rate``, so the
|
||
solver lane grades the solver against the *committed static gold*, and the hand-computed literal
|
||
tests (``test_literal_grid_values``, plus the inline ``(rate_a ± rate_b) × time`` in
|
||
``test_quantity_query_is_always_integral``) — **not** path-independence — are the anchor against a
|
||
shared ``effective_rate`` bug.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from generate.combined_rate_comprehension.model import CombinedRateProblem
|
||
from generate.meaning_graph.reader import Refusal
|
||
|
||
|
||
def solve_combined_rate(problem: CombinedRateProblem) -> int | Refusal:
|
||
"""Solve the queried slot exactly over the effective rate, or refuse with the closed taxonomy."""
|
||
eff = problem.effective_rate
|
||
if problem.query == "effective_rate":
|
||
return eff # the net rate is the answer, well-defined even when <= 0
|
||
if eff <= 0:
|
||
return Refusal("non_positive_net_rate", f"effective_rate={eff}")
|
||
if problem.query == "quantity":
|
||
assert problem.time is not None # guaranteed by the model's per-query slot guard
|
||
return eff * problem.time
|
||
# query == "time": exact integer division in the rate's denominator unit, or refuse.
|
||
assert problem.quantity is not None
|
||
if problem.quantity % eff != 0:
|
||
return Refusal("non_integer_solution", f"{problem.quantity}/{eff}")
|
||
return problem.quantity // eff
|
||
|
||
|
||
__all__ = ["solve_combined_rate"]
|