Skip to content

engine: mixed-arity multi-source reducer fails fragment compile (SUM(m1[d1,*]) + SUM(m2[*]) with 2-D m2) #781

Description

@bpowers

Problem

A variable whose equation sums two reducers over arrays of different arity fails to compile in the core engine -- with LTM disabled -- with a hard error:

Error { kind: Simulation, code: NotSimulatable, details: Some("failed to compile fragments for variables: two_mixed") }

Repro (verified)

TestProject fixture (src/simlin-engine/src/test_common.rs builder), compiled via assert_compiles_incremental():

TestProject::new("repro")
    .named_dimension("d1", &["a", "b"])
    .named_dimension("d2", &["c", "d"])
    .array_aux("m1[d1,d2]", "1")
    .array_aux("m2[d1,d2]", "2")
    .array_aux("two_mixed[d1]", "SUM(m1[d1,*]) + SUM(m2[*])")
    .assert_compiles_incremental(); // FAILS: NotSimulatable, "failed to compile fragments for variables: two_mixed"

The 1-D-co-source control variant compiles and simulates fine -- the only change is m2's declared dimensionality:

TestProject::new("control")
    .named_dimension("d1", &["a", "b"])
    .named_dimension("d2", &["c", "d"])
    .array_aux("m1[d1,d2]", "1")
    .array_aux("m2[d2]", "2")
    .array_aux("two_mixed[d1]", "SUM(m1[d1,*]) + SUM(m2[*])")
    .assert_compiles_incremental(); // passes

So the failing shape is: an apply-to-all equation over d1 containing a sliced partial reduce (SUM(m1[d1,*]), mixed iterated + wildcard axes) plus a whole-extent reduce of a 2-D array (SUM(m2[*])). Each reducer compiles fine in isolation; the combination in one equation fails.

Why it matters

  • This is a legal, natural model shape (e.g. "my row's total plus the global total") that hard-fails compilation instead of producing correct code or a diagnostic pointing at the equation construct.
  • It is a core compiler limitation, not an LTM one: the repro runs with ltm_enabled = false and involves no synthetic variables. It also constrains what LTM/test fixtures can express (the discovering fixture had to fall back to a 1-D co-source).

Severity: low-medium. Hard error, not silent miscomputation.

Component

src/simlin-engine/src/compiler/ -- likely the wildcard/A2A dimension-resolution path (context.rs with_preserved_wildcards reducer handling and/or subscript.rs expansion) where the bare m2[*] wildcard over a 2-D array must resolve under an active A2A dimension d1 while a sibling reducer pins d1 as iterated.

Possible approach

Trace the fragment-compile error for two_mixed (the compile_var_fragment / lower_var_fragment path drops the variable from the simulatable set); the per-reducer lowering presumably resolves the active-dimension context inconsistently when two reducers in one expression need different wildcard arities. A fix should gate on a regression test with the exact fixture above (both variants).

Context

Pre-existing core-compiler limitation discovered incidentally during the adversarial review of LTM T7 commits on branch ltm-shape-phase1 (shape-expressiveness work, epic #488) -- but reproduces with LTM fully disabled, so it is unrelated to LTM synthetic variables. Repro re-verified against current ltm-bug-batch before filing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingengineIssues with the rust-based simulation engine

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions