Measurement #1 of the field-reasoner falsifiable experiment: does the CL(4,1) field, given an honest metric encoding, read forward-substitutable quantitative-relational problems from TEXT with wrong==0? It does — 14/15 correct, 0 wrong, 1 refused (precision ceiling), scored against an independent arithmetic oracle. - generate/relational_field_reader.py: reads problem text into conformal points on the e1 number line; additive/part-whole relations are conformal TRANSLATOR versors (versor_apply(T_delta, embed[x]) == embed[x+delta], exact); the answer reads back by projective dehomogenization. Refusal-first: fences multiplicative/ratio (the sign/orientation-blind cases), the precision ceiling, non-forward-substitutable references, negatives. A per-step exactness self-check turns any f64 translator drift into a refusal (precision_drift) — it NEVER commits a wrong integer. Its parser is an independent reimplementation importing no generate.derivation/math_*. - evals/relational_metric/: independent arithmetic oracle (computes gold from the STRUCTURE, shares no code with the reader), 15-case fixture, and a runner that enforces gold integrity + wrong==0. - INV-25: relational_metric registered in INDEPENDENT_GOLD_LANES (oracle proven code-disjoint from the field reader and the algebra engine). The independently golded panel is now three domains: deductive, dimensional, relational-metric. Green: smoke 87, 53 architectural invariants, 16 new tests; deductive + dimensional lanes unperturbed (wrong=0).
133 lines
4 KiB
Python
133 lines
4 KiB
Python
"""Phase W — the geometric field reader on forward-substitutable relations.
|
|
|
|
Proves the field reads problem TEXT into an exact integer answer via conformal
|
|
translators + projective read-back, and REFUSES (never guesses) outside its sealed
|
|
metric grammar. wrong==0 is structural: every commit is an exact-integer read-back.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from generate.relational_field_reader import READER_LINEAGE, read_relational
|
|
|
|
|
|
# --- commits: the field reads correctly ------------------------------------
|
|
|
|
|
|
def test_fact_then_more_than():
|
|
r = read_relational(
|
|
"Tom has 3 marbles. Jane has 5 more marbles than Tom. "
|
|
"How many marbles does Jane have?"
|
|
)
|
|
assert not r.refused
|
|
assert r.answer == 8
|
|
assert r.answer_unit == "marbles"
|
|
assert r.reader_lineage == READER_LINEAGE
|
|
|
|
|
|
def test_fewer_than():
|
|
r = read_relational(
|
|
"Anna has 20 apples. Ben has 7 fewer apples than Anna. "
|
|
"How many apples does Ben have?"
|
|
)
|
|
assert not r.refused
|
|
assert r.answer == 13
|
|
|
|
|
|
def test_chained_forward_substitution():
|
|
r = read_relational(
|
|
"Tom has 4 coins. Jane has 6 more coins than Tom. "
|
|
"Sara has 10 more coins than Jane. How many coins does Sara have?"
|
|
)
|
|
assert not r.refused
|
|
assert r.answer == 20 # 4 -> 10 -> 20
|
|
|
|
|
|
def test_part_whole_sum_query():
|
|
r = read_relational(
|
|
"Tom has 3 marbles. Jane has 5 more marbles than Tom. "
|
|
"How many marbles do Tom and Jane have?"
|
|
)
|
|
assert not r.refused
|
|
assert r.answer == 11 # 3 + 8
|
|
|
|
|
|
def test_large_value_within_ceiling_is_exact():
|
|
# x=12345 already collapses f32 (the n_o weight loses the ±1 past ~4096);
|
|
# f64 + translator stays exact here.
|
|
r = read_relational(
|
|
"Tom has 12345 dollars. Jane has 5000 more dollars than Tom. "
|
|
"How many dollars does Jane have?"
|
|
)
|
|
assert not r.refused
|
|
assert r.answer == 17345
|
|
|
|
|
|
def test_never_commits_a_drifted_answer():
|
|
"""wrong==0 guard: at a scale where the translator sandwich loses f64 integer
|
|
exactness, the field REFUSES (precision_drift) rather than commit a wrong int."""
|
|
r = read_relational(
|
|
"Tom has 123456 dollars. Jane has 654321 more dollars than Tom. "
|
|
"How many dollars does Jane have?"
|
|
)
|
|
# Either it commits the EXACT answer, or it refuses — never a wrong integer.
|
|
assert r.refused or r.answer == 777777
|
|
if r.refused:
|
|
assert r.refusal_reason == "precision_drift"
|
|
|
|
|
|
# --- refusals: the field declines outside its sealed grammar ----------------
|
|
|
|
|
|
def test_refuses_multiplicative():
|
|
r = read_relational(
|
|
"Tom has 3 marbles. Jane has twice as many marbles as Tom. "
|
|
"How many marbles does Jane have?"
|
|
)
|
|
assert r.refused
|
|
assert r.refusal_reason == "fenced_multiplicative"
|
|
|
|
|
|
def test_refuses_times_cue():
|
|
r = read_relational(
|
|
"Tom has 3 marbles. Jane has 4 times as many marbles as Tom. "
|
|
"How many marbles does Jane have?"
|
|
)
|
|
assert r.refused
|
|
assert r.refusal_reason == "fenced_multiplicative"
|
|
|
|
|
|
def test_refuses_over_ceiling():
|
|
r = read_relational(
|
|
"Tom has 9000000 marbles. How many marbles does Tom have?"
|
|
)
|
|
assert r.refused
|
|
assert r.refusal_reason == "over_ceiling"
|
|
|
|
|
|
def test_refuses_forward_reference():
|
|
r = read_relational(
|
|
"Jane has 5 more marbles than Tom. Tom has 3 marbles. "
|
|
"How many marbles does Jane have?"
|
|
)
|
|
assert r.refused
|
|
assert r.refusal_reason == "non_forward_substitutable"
|
|
|
|
|
|
def test_refuses_no_question():
|
|
r = read_relational("Tom has 3 marbles. Jane has 5 more marbles than Tom.")
|
|
assert r.refused
|
|
assert r.refusal_reason == "no_query"
|
|
|
|
|
|
def test_refuses_negative_quantity():
|
|
r = read_relational(
|
|
"Tom has 3 marbles. Jane has 5 fewer marbles than Tom. "
|
|
"How many marbles does Jane have?"
|
|
)
|
|
assert r.refused
|
|
assert r.refusal_reason == "negative_quantity"
|
|
|
|
|
|
def test_refuses_empty():
|
|
assert read_relational("").refused
|
|
assert read_relational(" ").refusal_reason == "empty_input"
|