spec: 0032 correct test 5 fixture nesting (boss-signed)
Test 5's asymmetric-collision fixture asserted a root-level param_space
["sma.length"] while also being "test 2's fixture with one leg swapped" (nested)
— a contradiction: check_fan_in_distinguishability only descends into composites,
so a root-level collision is not rejected today (not RED-first). Caught at plan
time while writing the verbatim fixture body.
Corrected: test 5 nests the asymmetric collision in an inner composite `asym`
(param-bearing Sma "sma" + paramless Pass1 .named("sma") + Sub, both leaves on
role price fanning into the Sub) under a source-bound root, asserting
param_space() == ["asym.sma.length"] (the single injective entry — the paramless
leg contributes no path) and that compile_with_params(&[I64(2)]) is Ok after.
Re-grounded PASS, re-panel unanimous SOUND. Forward correction on top of 7f059d0
(main is forward-only — no rewind of the boss-signed spec).
refs #59
This commit is contained in:
@@ -377,13 +377,19 @@ positional filter per invocation).
|
||||
4. **Unchanged green** `interchangeable_fan_in_allowed` (~1531): two **param-less**
|
||||
`Pass1` into a `Join2` → still `compile().is_ok()`. Paramless nodes contribute no
|
||||
`param_space()` path, so no duplicate; the C9 interchangeability survives.
|
||||
5. **New** `asymmetric_node_name_collision_compiles` — pins the intentional drop:
|
||||
a param-bearing `Sma` (default name `"sma"`) and a **paramless** `Pass1`
|
||||
`.named("sma")`, both on role `price`, fanning into one `Sub`. Equal node-name
|
||||
5. **New** `asymmetric_node_name_collision_compiles` — pins the intentional drop.
|
||||
The asymmetric collision must sit **inside a composite** for the old check to
|
||||
reach it (`check_fan_in_distinguishability` only descends into composites; a
|
||||
root-level fan-in is never checked), so it reuses test 2's nested shape: an inner
|
||||
composite `asym` holding a param-bearing `Sma` (default name `"sma"`), a
|
||||
**paramless** `Pass1` `.named("sma")`, and a `Sub`, with both leaves on role
|
||||
`price` fanning into the `Sub`; `asym` sits under a source-bound `root`
|
||||
(`Some(ScalarKind::F64)`), exactly like `sma_cross_under_root`. Equal node-name
|
||||
signatures + one param → **rejected today** (`IndistinguishableFanIn`); after the
|
||||
change `param_space()` is a single entry `["sma.length"]` (injective), so
|
||||
`compile_with_params(&[Scalar::I64(2)])` is `Ok`. RED-green flip is the *reverse*
|
||||
of test 3 — what the old check rejected, the new one admits, by design.
|
||||
change `param_space()` is the single entry `["asym.sma.length"]` (injective — the
|
||||
paramless leg contributes no path), so `compile_with_params(&[Scalar::I64(2)])`
|
||||
is `Ok`. The RED-green flip is the *reverse* of test 3 — what the old check
|
||||
rejected, the new one admits, by design.
|
||||
6. **The #59 test** `by_name_bootstrap_of_unnamed_cross_reports_duplicate_path`:
|
||||
`bp.with("sma_cross.sma.length", 2).bootstrap()` on an unnamed cross →
|
||||
`Err(BindError::Compile(CompileError::DuplicateParamPath("sma_cross.sma.length".into())))`,
|
||||
|
||||
Reference in New Issue
Block a user