core/generate/derivation/__init__.py
Shay 5a9454af20 feat(adr-0176-ms2): multi-step chain model — text + comparative operands
MS-2 of multi-step composition. Extends the derivation model so a chain mixes
text-quantity operands and COMPARATIVE-scalar operands (twice->x2, 'N times'->xN,
half->x0.5), self-verifying the whole chain with completeness over body+question
and question-target matching.

- model.py: Step gains comparative flag.
- comparatives.py: ComparativeScalar gains number_token (the '<N> times' number,
  so completeness counts the consumed body quantity); comparative_step(cs) bridges
  a scalar into a Step (operand grounded by cue, not a text value token).
- verify.py: self_verifies exempts comparative operands from value-grounding
  (clause 1) — they are cue-grounded (clause 2); completeness (Counter) counts a
  digit comparative's number_token as consuming the body quantity. Adds target_units
  to select_self_verified: a chain whose answer_unit isn't the asked unit is dropped
  (question-target match; empty target_units imposes no constraint).

Proves the multi-step shapes from the gold structures: 0024 (text sum then 'three
times' scale -> 438), 0033 father-chain (digit-comparative '7 times' + fixed 'half'
+ text add -> 47). Full 0033 DAG (quantity reuse + the question's 25) deferred.

25 MS-2 tests; full derivation surface 69/69 (3a/3b/comparatives/ms1/ms2); ruff
clean; smoke 67. Not wired into serving (model ready for MS-3 target-guided search).
2026-05-28 16:35:41 -07:00

43 lines
1.2 KiB
Python

"""ADR-0175 Phase 3 — grounded derivation search + self-verification gate.
Phase 3a (this surface): the self-verification gate — grounded operands ∧
grounded operation cues ∧ unit consistency ∧ uniqueness. The wrong=0-critical
guard that keeps the (Phase 3b) bounded search honest.
"""
from __future__ import annotations
from generate.derivation.comparatives import (
ComparativeScalar,
comparative_step,
extract_comparative_scalars,
)
from generate.derivation.extract import extract_quantities
from generate.derivation.model import GroundedDerivation, Quantity, Step, VALID_OPS
from generate.derivation.search import MULTIPLICATIVE_CUES, search_multiplicative
from generate.derivation.target import Target, extract_target
from generate.derivation.verify import (
Resolution,
SelfVerification,
select_self_verified,
self_verifies,
)
__all__ = [
"ComparativeScalar",
"GroundedDerivation",
"MULTIPLICATIVE_CUES",
"Quantity",
"Resolution",
"SelfVerification",
"Step",
"Target",
"VALID_OPS",
"comparative_step",
"extract_comparative_scalars",
"extract_quantities",
"extract_target",
"search_multiplicative",
"select_self_verified",
"self_verifies",
]