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.

Activity

  1. added
    bugSomething isn't working
    engineIssues with the rust-based simulation engine
    on Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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